1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
| /* heap This question requires you to implement a binary heap function */ // I AM NOT DONE
use std::cmp::Ord; use std::default::Default;
pub struct Heap<T> where T: Default, { count: usize, items: Vec<T>, comparator: fn(&T, &T) -> bool, }
impl<T> Heap<T> where T: Default, { pub fn new(comparator: fn(&T, &T) -> bool) -> Self { Self { count: 0, items: vec![T::default()], comparator, } }
pub fn len(&self) -> usize { self.count }
pub fn is_empty(&self) -> bool { self.len() == 0 }
pub fn add(&mut self, value: T) { //TODO self.items.push(value); self.count += 1; let mut idx = self.count;
while idx > 1 && (self.comparator)(&self.items[idx], &self.items[idx / 2]) == true { self.items.swap(idx, idx / 2); idx /= 2; };//加入后不断上浮对父节点进行比较直到到达顶点或小/大于父节点 }
fn parent_idx(&self, idx: usize) -> usize { idx / 2 }
fn children_present(&self, idx: usize) -> bool { self.left_child_idx(idx) <= self.count }
fn left_child_idx(&self, idx: usize) -> usize { idx * 2 }
fn right_child_idx(&self, idx: usize) -> usize { self.left_child_idx(idx) + 1 }
fn smallest_child_idx(&self, idx: usize) -> usize { //TODO let left_child = self.left_child_idx(idx); let right_child = self.right_child_idx(idx); if right_child > self.count || (self.comparator)(&self.items[left_child], &self.items[right_child]) == true { left_child } else { right_child }//right_child不存在或左节点比右节点大/小 } }
impl<T> Heap<T> where T: Default + Ord, { /// Create a new MinHeap pub fn new_min() -> Self { Self::new(|a, b| a < b) }
/// Create a new MaxHeap pub fn new_max() -> Self { Self::new(|a, b| a > b) } }
impl<T> Iterator for Heap<T> where T: Default+Copy, { type Item = T;
fn next(&mut self) -> Option<T> { //TODO if !self.is_empty() { self.items.swap(1, self.count); let res = self.items.swap_remove(self.count); self.count -= 1; // SWIM let mut idx: usize = 1; let mut smallest_child_idx = self.smallest_child_idx(idx); while smallest_child_idx <= self.count && (self.comparator)(&self.items[smallest_child_idx], &self.items[idx]) { self.items.swap(smallest_child_idx, idx); idx = smallest_child_idx; smallest_child_idx = self.smallest_child_idx(smallest_child_idx); }; Some(res) } else { None } }//如果堆不为空,交换顶点和最小节点,然后检测下沉,如果顶点小/大于子节点,则不断下沉交换。 //因为add的上浮操作导致堆的顶点的下方是无序的,需要不断下沉保证堆的性质 }
pub struct MinHeap;
impl MinHeap { #[allow(clippy::new_ret_no_self)] pub fn new<T>() -> Heap<T> where T: Default + Ord, { Heap::new(|a, b| a < b) } }
pub struct MaxHeap;
impl MaxHeap { #[allow(clippy::new_ret_no_self)] pub fn new<T>() -> Heap<T> where T: Default + Ord, { Heap::new(|a, b| a > b) } }
#[cfg(test)] mod tests { use super::*; #[test] fn test_empty_heap() { let mut heap = MaxHeap::new::<i32>(); assert_eq!(heap.next(), None); }
#[test] fn test_min_heap() { let mut heap = MinHeap::new(); heap.add(4); heap.add(2); heap.add(9); heap.add(11); assert_eq!(heap.len(), 4); assert_eq!(heap.next(), Some(2)); assert_eq!(heap.next(), Some(4)); assert_eq!(heap.next(), Some(9)); heap.add(1); assert_eq!(heap.next(), Some(1)); }
#[test] fn test_max_heap() { let mut heap = MaxHeap::new(); heap.add(4); heap.add(2); heap.add(9); heap.add(11); assert_eq!(heap.len(), 4); assert_eq!(heap.next(), Some(11)); assert_eq!(heap.next(), Some(9)); assert_eq!(heap.next(), Some(4)); heap.add(1); assert_eq!(heap.next(), Some(2)); } }
|