use std::mem;
fn sift_up<T: PartialOrd>(heap: &mut [T]) {
let mut i = heap.len();
let mut j = i/2;
while (j>0) && (heap[i-1]<heap[j-1]) {
heap.swap(i-1, j-1);
i = j;
j = j/2;
}
}
fn sift_down<T: PartialOrd>(heap: &mut [T], mut i: usize) {
i = i+1;
let mut j = i*2;
let mut k = j+1;
if (k<=heap.len()) && (heap[k-1]<heap[j-1]) {
j = k;
}
while (j<=heap.len()) && (heap[j-1]<heap[i-1]) {
heap.swap(i-1, j-1);
i = j;
j = i*2;
k = j+1;
if (k<=heap.len()) && (heap[k-1]<heap[j-1]) {
j = k;
}
}
}
pub fn heapify<T: PartialOrd>(heap: &mut [T]) {
for i in (0..((heap.len()-1)/2)).rev() {
sift_down(heap, i);
}
}
pub fn verify_heap<T:PartialOrd>(heap: &[T]) -> bool {
for i in 0..((heap.len()-1)/2) {
if heap[i]>heap[((i+1)*2-1)] || heap[i]>heap[((i+1)*2)] { return false; }
}
true
}
pub struct BoundedBinaryHeaper<'a, T: 'a> {
len: usize,
heap: &'a mut [T],
}
impl<'a, T: 'a+PartialOrd> BoundedBinaryHeaper<'a, T>
{
pub fn from(slice: &'a mut [T]) -> BoundedBinaryHeaper<'a, T> {
heapify(slice);
BoundedBinaryHeaper {
len: slice.len(),
heap: slice,
}
}
pub fn from_empty_slice(slice: &'a mut [T]) -> BoundedBinaryHeaper<'a, T> {
BoundedBinaryHeaper {
len: 0,
heap: slice,
}
}
pub fn push(&mut self, mut elem: T) -> Option<T> {
if self.len<self.capacity() {
self.heap[self.len]=elem;
self.len+=1;
let l=self.len;
sift_up(&mut self.heap[0..l]);
None
} else if (self.len>0) && (elem>=self.heap[0]) {
mem::swap(&mut elem, &mut self.heap[0]);
sift_down(self.heap, 0);
Some(elem)
} else {
Some(elem)
}
}
pub fn pop(&mut self) -> Option<&T> {
if self.len>0 {
self.heap.swap(0, self.len-1);
self.len-=1;
let l=self.len;
sift_down(&mut self.heap[0..l], 0);
Some(&self.heap[self.len])
} else {
None
}
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
return self.len()==0
}
pub fn capacity(&self) -> usize {
self.heap.len()
}
pub fn peek(&self) -> Option<&T> {
if self.len>0 {
Some(&self.heap[0])
} else {
None
}
}
}
pub struct BoundedBinaryHeap<T>
{
heap: Vec<T>,
capacity: usize,
len: usize
}
impl<T: PartialOrd+Clone> BoundedBinaryHeap<T>
{
pub fn new(capacity: usize) -> BoundedBinaryHeap<T> {
BoundedBinaryHeap {
heap: Vec::with_capacity(capacity),
capacity: capacity,
len: 0
}
}
pub fn from(slice: &[T]) -> BoundedBinaryHeap<T> {
let mut h = BoundedBinaryHeap {
heap: slice.to_vec(),
capacity: slice.len(),
len: slice.len()
};
heapify(&mut h.heap);
h
}
pub fn from_slice_with_capacity(slice: &[T], capacity: usize) -> BoundedBinaryHeap<T> {
let mut h = BoundedBinaryHeap {
heap: slice.to_vec(),
capacity: capacity,
len: slice.len()
};
heapify(&mut h.heap);
h
}
pub fn push(&mut self, mut elem: T) -> Option<T> {
if self.len<self.capacity() {
self.len+=1;
self.heap.push(elem);
let l=self.len;
sift_up(&mut self.heap[0..l]);
None
} else if (self.len>0) && (elem>=self.heap[0]) {
mem::swap(&mut elem, &mut self.heap[0]);
sift_down(&mut self.heap, 0);
Some(elem)
} else {
Some(elem)
}
}
pub fn pop(&mut self) -> Option<T> {
if self.len>0 {
self.heap.swap(0, self.len-1);
self.len-=1;
let l=self.len;
sift_down(&mut self.heap[0..l], 0);
Some(self.heap.swap_remove(self.len))
} else {
None
}
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
return self.len()==0
}
pub fn capacity(&self) -> usize {
self.capacity
}
pub fn peek(&self) -> Option<&T> {
if self.len>0 {
Some(&self.heap[0])
} else {
None
}
}
}