|
|
@@ -0,0 +1,55 @@ |
|
|
|
use std::mem; |
|
|
|
|
|
|
|
pub struct BinHeap<T> { |
|
|
|
data: Vec<T>, |
|
|
|
} |
|
|
|
|
|
|
|
impl<T: Ord> BinHeap<T> { |
|
|
|
pub fn new() -> BinHeap<T> { |
|
|
|
BinHeap{ data: vec![] } |
|
|
|
} |
|
|
|
|
|
|
|
pub fn insert(&mut self, elem: T) { |
|
|
|
self.data.push(elem); |
|
|
|
self.bubble_up(self.len() - 1); |
|
|
|
} |
|
|
|
|
|
|
|
pub fn pop(&mut self) -> Option<T> { |
|
|
|
if self.len() == 0 { return None } |
|
|
|
let val = self.data.swap_remove(0); |
|
|
|
self.bubble_down(0); |
|
|
|
Some(val) |
|
|
|
} |
|
|
|
|
|
|
|
fn bubble_up(&mut self, index: usize) { |
|
|
|
match index { |
|
|
|
0 => (), |
|
|
|
x if x <= self.len() => { |
|
|
|
let parent = (index - 1) / 2; |
|
|
|
if self.data[index] > self.data[parent] { |
|
|
|
self.data.swap(index, parent); |
|
|
|
self.bubble_up(parent); |
|
|
|
} |
|
|
|
}, |
|
|
|
// we shouldn't ever be calling bubble_up with the index out of bounds |
|
|
|
_ => panic!("bubble_up: index out of bounds") |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
fn bubble_down(&mut self, index: usize) { |
|
|
|
// index <= (len - 1) / 2 is true if and only if data[index] has children |
|
|
|
if index <= (self.len() - 1) / 2 { |
|
|
|
let largest_child_idx = match self.data[2*index+1] > self.data[2*index+2] { |
|
|
|
true => 2 * index + 1, |
|
|
|
false => 2 * index + 2, |
|
|
|
}; |
|
|
|
if self.data[index] < self.data[largest_child_idx] { |
|
|
|
self.data.swap(index, largest_child_idx); |
|
|
|
self.bubble_down(largest_child_idx); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
pub fn len(&self) -> usize { self.data.len() } |
|
|
|
} |