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}