graph_collections/min_heap.rs
1/// A binary min-heap backed by a [`Vec`].
2///
3/// The smallest element (by [`Ord`]) is always at the top. Every push and pop
4/// runs in **O(log n)**; peek is **O(1)**.
5///
6/// # Examples
7///
8/// ```
9/// use graph_collections::MinHeap;
10///
11/// let mut heap = MinHeap::new();
12/// heap.push(5u32);
13/// heap.push(1);
14/// heap.push(3);
15///
16/// assert_eq!(heap.peek(), Some(&1));
17/// assert_eq!(heap.pop(), Some(1));
18/// assert_eq!(heap.pop(), Some(3));
19/// assert_eq!(heap.pop(), Some(5));
20/// assert!(heap.is_empty());
21/// ```
22#[derive(Debug, Clone, PartialEq, Eq)]
23pub struct MinHeap<T: Ord> {
24 data: Vec<T>,
25}
26
27impl<T: Ord> MinHeap<T> {
28 #[inline]
29 fn parent(idx: usize) -> usize {
30 (idx - 1) / 2
31 }
32
33 #[inline]
34 fn left(idx: usize) -> usize {
35 2 * idx + 1
36 }
37
38 #[inline]
39 fn right(idx: usize) -> usize {
40 2 * idx + 2
41 }
42}
43
44impl<T: Ord> Default for MinHeap<T> {
45 fn default() -> Self {
46 Self { data: Vec::new() }
47 }
48}
49
50impl<T: Ord> MinHeap<T> {
51 /// Creates a new, empty min-heap.
52 ///
53 /// # Examples
54 ///
55 /// ```
56 /// use graph_collections::MinHeap;
57 ///
58 /// let heap: MinHeap<u32> = MinHeap::new();
59 /// assert!(heap.is_empty());
60 /// ```
61 pub fn new() -> Self {
62 Self::default()
63 }
64
65 /// Creates a new, empty min-heap with at least the given capacity
66 /// pre-allocated, avoiding reallocations for the first `capacity` pushes.
67 ///
68 /// # Examples
69 ///
70 /// ```
71 /// use graph_collections::MinHeap;
72 ///
73 /// let heap: MinHeap<u32> = MinHeap::with_capacity(64);
74 /// assert!(heap.is_empty());
75 /// ```
76 pub fn with_capacity(capacity: usize) -> Self {
77 Self {
78 data: Vec::with_capacity(capacity),
79 }
80 }
81}
82
83impl<T: Ord> MinHeap<T> {
84 /// Returns `true` if the heap contains no elements.
85 ///
86 /// # Examples
87 ///
88 /// ```
89 /// use graph_collections::MinHeap;
90 ///
91 /// let mut heap: MinHeap<u32> = MinHeap::new();
92 /// assert!(heap.is_empty());
93 /// heap.push(1);
94 /// assert!(!heap.is_empty());
95 /// ```
96 #[inline]
97 pub fn is_empty(&self) -> bool {
98 self.data.is_empty()
99 }
100
101 /// Returns the number of elements in the heap.
102 ///
103 /// # Examples
104 ///
105 /// ```
106 /// use graph_collections::MinHeap;
107 ///
108 /// let mut heap: MinHeap<u32> = MinHeap::new();
109 /// assert_eq!(heap.len(), 0);
110 /// heap.push(1);
111 /// heap.push(2);
112 /// assert_eq!(heap.len(), 2);
113 /// ```
114 #[must_use]
115 #[inline]
116 pub fn len(&self) -> usize {
117 self.data.len()
118 }
119}
120
121impl<T: Ord> MinHeap<T> {
122 /// Returns a reference to the **minimum** element without removing it,
123 /// or `None` if the heap is empty.
124 ///
125 /// # Examples
126 ///
127 /// ```
128 /// use graph_collections::MinHeap;
129 ///
130 /// let mut heap: MinHeap<u32> = MinHeap::new();
131 /// assert_eq!(heap.peek(), None);
132 /// heap.push(5);
133 /// heap.push(1);
134 /// heap.push(3);
135 /// assert_eq!(heap.peek(), Some(&1)); // minimum, not removed
136 /// assert_eq!(heap.len(), 3);
137 /// ```
138 #[must_use]
139 #[inline]
140 pub fn peek(&self) -> Option<&T> {
141 self.data.first()
142 }
143}
144
145impl<T: Ord> MinHeap<T> {
146 /// Inserts `value` into the heap in **O(log n)**.
147 ///
148 /// After each push, `peek` returns the overall minimum.
149 ///
150 /// # Examples
151 ///
152 /// ```
153 /// use graph_collections::MinHeap;
154 ///
155 /// let mut heap: MinHeap<u32> = MinHeap::new();
156 /// heap.push(3);
157 /// heap.push(1);
158 /// heap.push(2);
159 /// assert_eq!(heap.peek(), Some(&1));
160 /// ```
161 pub fn push(&mut self, value: T) {
162 self.data.push(value);
163 let last = self.data.len() - 1;
164 self.sift_up(last);
165 }
166
167 /// Restores the heap property upward from `idx`.
168 ///
169 /// Algorithm:
170 /// 1. While `idx > 0` and `data[idx] < data[parent(idx)]`, swap upward.
171 fn sift_up(&mut self, mut idx: usize) {
172 while idx > 0 {
173 let p = Self::parent(idx);
174 if self.data[idx] < self.data[p] {
175 self.data.swap(idx, p);
176 idx = p;
177 } else {
178 break;
179 }
180 }
181 }
182}
183
184impl<T: Ord> MinHeap<T> {
185 /// Removes and returns the **minimum** element in **O(log n)**,
186 /// or `None` if the heap is empty.
187 ///
188 /// # Examples
189 ///
190 /// ```
191 /// use graph_collections::MinHeap;
192 ///
193 /// let mut heap: MinHeap<u32> = MinHeap::new();
194 /// assert_eq!(heap.pop(), None);
195 /// heap.push(5);
196 /// heap.push(1);
197 /// heap.push(3);
198 /// assert_eq!(heap.pop(), Some(1));
199 /// assert_eq!(heap.pop(), Some(3));
200 /// assert_eq!(heap.pop(), Some(5));
201 /// assert_eq!(heap.pop(), None);
202 /// ```
203 pub fn pop(&mut self) -> Option<T> {
204 if self.data.is_empty() {
205 return None;
206 }
207 let last = self.data.len() - 1;
208 self.data.swap(0, last);
209 let min = self.data.pop();
210 if !self.data.is_empty() {
211 self.sift_down(0);
212 }
213 min
214 }
215
216 /// Restores the heap property downward from `idx`.
217 ///
218 /// Algorithm:
219 /// 1. Find the smallest among `data[idx]`, left child, and right child.
220 /// 2. If a child is smaller, swap and recurse downward.
221 fn sift_down(&mut self, mut idx: usize) {
222 let len = self.data.len();
223 loop {
224 let left = Self::left(idx);
225 let right = Self::right(idx);
226 let mut smallest = idx;
227
228 if left < len && self.data[left] < self.data[smallest] {
229 smallest = left;
230 }
231 if right < len && self.data[right] < self.data[smallest] {
232 smallest = right;
233 }
234
235 if smallest == idx {
236 break;
237 }
238 self.data.swap(idx, smallest);
239 idx = smallest;
240 }
241 }
242
243 /// Removes all elements from the heap.
244 ///
245 /// # Examples
246 ///
247 /// ```
248 /// use graph_collections::MinHeap;
249 ///
250 /// let mut heap: MinHeap<u32> = (1..=5).collect();
251 /// heap.clear();
252 /// assert!(heap.is_empty());
253 /// ```
254 #[inline]
255 pub fn clear(&mut self) {
256 self.data.clear();
257 }
258}
259
260impl<T: Ord> FromIterator<T> for MinHeap<T> {
261 /// Builds a `MinHeap` from any iterator.
262 ///
263 /// Uses the O(n) heapify algorithm (build-heap) rather than O(n log n)
264 /// successive pushes.
265 ///
266 /// # Examples
267 ///
268 /// ```
269 /// use graph_collections::MinHeap;
270 ///
271 /// let heap: MinHeap<u32> = vec![5, 3, 1, 4, 2].into_iter().collect();
272 /// assert_eq!(heap.peek(), Some(&1));
273 /// assert_eq!(heap.len(), 5);
274 /// ```
275 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
276 let data: Vec<T> = iter.into_iter().collect();
277 let mut heap = Self { data };
278 // Heapify: sift down every non-leaf node from bottom to top.
279 if heap.data.len() > 1 {
280 let last_parent = (heap.data.len() - 2) / 2;
281 for i in (0..=last_parent).rev() {
282 heap.sift_down(i);
283 }
284 }
285 heap
286 }
287}
288
289impl<T: Ord> Extend<T> for MinHeap<T> {
290 /// Pushes all elements produced by the iterator into the heap.
291 ///
292 /// # Examples
293 ///
294 /// ```
295 /// use graph_collections::MinHeap;
296 ///
297 /// let mut heap: MinHeap<u32> = MinHeap::new();
298 /// heap.push(10);
299 /// heap.extend([2, 7, 1]);
300 /// assert_eq!(heap.peek(), Some(&1));
301 /// assert_eq!(heap.len(), 4);
302 /// ```
303 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
304 for item in iter {
305 self.push(item);
306 }
307 }
308}
309
310/// Consuming iterator that yields elements in **ascending (sorted) order**.
311///
312/// Each call to `next` performs one heap pop, so the overall traversal is O(n log n).
313pub struct MinHeapIntoIter<T: Ord> {
314 heap: MinHeap<T>,
315}
316
317impl<T: Ord> Iterator for MinHeapIntoIter<T> {
318 type Item = T;
319
320 fn next(&mut self) -> Option<T> {
321 self.heap.pop()
322 }
323
324 fn size_hint(&self) -> (usize, Option<usize>) {
325 let n = self.heap.len();
326 (n, Some(n))
327 }
328}
329
330impl<T: Ord> IntoIterator for MinHeap<T> {
331 type Item = T;
332 type IntoIter = MinHeapIntoIter<T>;
333
334 /// Consumes the heap and yields elements in **ascending order**.
335 ///
336 /// # Examples
337 ///
338 /// ```
339 /// use graph_collections::MinHeap;
340 ///
341 /// let heap: MinHeap<u32> = vec![4, 2, 5, 1, 3].into_iter().collect();
342 /// let sorted: Vec<u32> = heap.into_iter().collect();
343 /// assert_eq!(sorted, [1, 2, 3, 4, 5]);
344 /// ```
345 fn into_iter(self) -> Self::IntoIter {
346 MinHeapIntoIter { heap: self }
347 }
348}