const HEAP_CONTAINER_MAX_SIZE: usize = 2147483647;
pub trait HeapContainer {
type T: PartialEq + PartialOrd;
fn size(&self) -> usize;
fn less(&self, i: usize, j: usize) -> bool;
fn swap(&mut self, usize, usize);
fn push_back(&mut self, _: Self::T);
fn pop_back(&mut self) -> Option<Self::T>;
}
pub struct Heap<C: HeapContainer> {
data: C,
}
impl<C: HeapContainer> Heap<C> {
pub fn new(c: C) -> Heap<C> {
Heap {
data: c,
}
}
pub fn size(&self) -> usize {
self.data.size()
}
pub fn push(&mut self, t: C::T) {
let n = self.size();
self.data.push_back(t);
self._up(n);
}
pub fn pop(&mut self) -> Option<C::T> {
let len = self.size();
if len == 0 {
return None;
}
let n = len - 1;
self.data.swap(0, n);
self._down(0, n);
self.data.pop_back()
}
pub fn remove(&mut self, i: usize) -> Option<C::T> {
let n = self.size() - 1;
if n != i {
self.data.swap(i, n);
self._down(i, n);
self._up(i);
}
self.data.pop_back()
}
pub fn fix(&mut self, i: usize) {
let len = self.size();
self._down(i, len);
self._up(i);
}
fn _up(&mut self, i: usize) {
let mut i = i;
while i > 0 {
let j = (i-1)/2;
if i == j || !self.data.less(i, j) {
break
}
self.data.swap(i, j);
i = j;
}
}
fn _down(&mut self, i: usize, n: usize) {
let mut i = i;
loop {
let j1 = 2*i+1;
if j1 >=n || j1 > HEAP_CONTAINER_MAX_SIZE {
break;
}
let mut j = j1;
let j2 = j1+1;
if j2 < n && !self.data.less(j1, j2) {
j = j2;
}
if !self.data.less(j, i) {
break;
}
self.data.swap(i, j);
i = j;
}
}
}