08-heaps
Top-K with a Heap
Keep only the largest k values by maintaining a small min-heap.
Algorithm
Steps
- Store the heap in an array.
- Compare parent and child indexes instead of building explicit tree nodes.
- Swap only when the heap order is violated.
- Print the deterministic final heap state for replay comparison.
Complexity
- Time: O(n log k)
- Space: O(k)
bounded heap
For top-k largest values, a min-heap of size k keeps the current cutoff at the root.
Rust DSA Implementation
basic.rs
fn list_string(values: &[i32]) -> String {
format!("[{}]", values.iter().map(|v| v.to_string()).collect::<Vec<_>>().join(", "))
}
fn heap_insert(heap: &mut Vec<i32>, value: i32) {
heap.push(value);
let mut child = heap.len() - 1;
while child > 0 {
let parent = (child - 1) / 2;
if heap[parent] <= heap[child] { break; }
heap.swap(parent, child);
child = parent;
}
}
fn heap_pop(heap: &mut Vec<i32>) -> i32 {
let smallest = heap[0];
let last = heap.pop().unwrap();
heap[0] = last;
let mut parent = 0;
loop {
let left = parent * 2 + 1;
let right = left + 1;
if left >= heap.len() { break; }
let mut child = left;
if right < heap.len() && heap[right] < heap[left] { child = right; }
if heap[parent] <= heap[child] { break; }
heap.swap(parent, child);
parent = child;
}
smallest
}
fn main() { let values = [5, 1, 9, 3, 7, 2]; let mut heap = Vec::new(); for value in values { heap_insert(&mut heap, value); if heap.len() > 3 { heap_pop(&mut heap); } } heap.sort_by(|a, b| b.cmp(a)); println!("{}", list_string(&heap)); }
Output
[9, 7, 5]
Implementation notes
mainstores the input in a fixed[i32; 6]array and keeps the working heap inlet mut heap = Vec::new(), a mutableVec<i32>.- Each
for value in valuesiteration copies ani32value intoheap_insert(&mut heap, value). The heap helper mutates the same vector withpush, parent index(child - 1) / 2, andheap.swap(parent, child). - The heap is a min-heap: helper comparisons use
<=to keep the smallest retained top-k value at index0. - Top-k size is enforced by
if heap.len() > 3 { heap_pop(&mut heap); }.heap_popremoves and returns the minimum withheap.pop().unwrap(), root replacement, child indexesparent * 2 + 1andleft + 1, smaller-child selection, and in-place swaps. - The popped value is not collected; only the final bounded heap remains. The
trace states are
[5],[1, 5],[1, 5, 9],[3, 5, 9],[5, 7, 9], and[5, 7, 9]after considering2. - Before printing,
heap.sort_by(|a, b| b.cmp(a))mutates the retained values into high-to-low order.list_string(&heap)borrows the vector as a slice andprintln!("{}", ...)prints[9, 7, 5].