Heaps: the smallest is always on top
A heap is a binary tree with one rule: every parent is smaller than or equal to its children (a min-heap; a max-heap flips it). Unlike a BST, there's no order between siblings, so you can't search a heap for an arbitrary key. What you get instead is instant access to the minimum: it's always the root.
Adding an item and removing the minimum are both O(log n): the new item bubbles up, or the item moved into the root sinks down, along one path. And a heap is stored as a plain array, no pointers: the children of position i are at 2i+1 and 2i+2.
A hospital emergency room: the next patient isn't whoever came first but whoever is most urgent. New patients arrive constantly, and the most urgent one must be found instantly.
In code: Python · Rust
import heapq
er = []
heapq.heappush(er, (2, "broken arm")) # (priority, item)
heapq.heappush(er, (1, "chest pain"))
heapq.heappush(er, (3, "cough"))
heapq.heappop(er) # (1, 'chest pain'): smallest first
heapq.nsmallest(2, [5, 1, 4, 2]) # [1, 2]use std::collections::BinaryHeap;
use std::cmp::Reverse;
// BinaryHeap is a MAX-heap; wrap in Reverse for smallest-first
let mut er = BinaryHeap::new();
er.push(Reverse((2, "broken arm")));
er.push(Reverse((1, "chest pain")));
let next = er.pop(); // Some(Reverse((1, "chest pain")))- Python's heapq is a min-heap over a plain list; Rust's BinaryHeap is a max-heap. A common source of bugs when switching languages.
- Tuples compare element by element, which is why (priority, item) works as a heap entry.