Heaps beyond the binary heap, and the operations that motivate them: meld (merge two heaps) and decrease-key.
The comparison
| Heap | push | pop-min | decrease-key | meld | Practical? |
|---|---|---|---|---|---|
| Binary | yes — best constant | ||||
| Binomial | rarely | ||||
| Leftist | — | yes, when melding | |||
| Skew | am. | am. | — | am. | yes — 20 lines |
| Pairing | am. | am. | yes — good constant | ||
| Fibonacci | am. | am. | am. | no — huge constant | |
| Randomized meldable | exp. | exp. | — | exp. | yes — 10 lines |
| Brodal queue | no — theoretical | ||||
| Hollow heap | am. | am. | no | ||
| Soft heap | am. | am. | — | specialised — see Chazelle |
Meldable heaps — the ones worth writing
Randomized meldable heap
Ten lines, expected for everything, and it is the easiest meldable heap to get right.
struct Node { int key; Node *l = nullptr, *r = nullptr; };
mt19937 rng(random_device{}());
Node* merge(Node* a, Node* b) {
if (!a || !b) return a ? a : b;
if (a->key > b->key) swap(a, b); // min-heap
if (rng() & 1) swap(a->l, a->r);
a->l = merge(a->l, b);
return a;
}
void push(Node*& h, int key) { h = merge(h, new Node{key}); }
void pop(Node*& h) { h = merge(h->l, h->r); }The random swap keeps the expected depth without any balancing bookkeeping.
Leftist heap
Deterministic version: store the null-path length at each node and always merge into the shorter side. Guarantees worst case rather than expected.
Skew heap
Leftist without the bookkeeping: always swap children after merging. amortized, and even shorter than the randomized version.
Why melding matters
Melding turns “combine two collections” from into , which matters in:
- Small-to-large on trees — merge children’s heaps in tree DP without the from copying
- Chu-Liu/Edmonds — the implementation melds heaps of incoming edges when contracting cycles
- Eppstein’s $k$ shortest paths — needs persistent meldable heaps
- Offline problems where sets merge irreversibly
Why Fibonacci heaps are a trap
The amortized decrease-key improves Dijkstra from to — on paper. In practice the constant factor and the pointer chasing make it slower than a binary heap for every graph size that fits in memory. Nobody uses Fibonacci heaps in contests, and few use them in production.
The lesson generalises: an asymptotic improvement bought with a large constant and poor cache behaviour is usually not an improvement.
Indexed heaps
When you truly need decrease-key without lazy deletion, keep a pos[] array mapping element ids to heap positions and update it during every sift. Adds memory and some bookkeeping. In practice, lazy deletion (push a duplicate, skip stale entries) is simpler and just as fast.
Soft heaps
Chazelle’s soft heap allows amortized operations by corrupting at most an fraction of keys (their stored values may be increased). Used to break the barrier in MST and to give a clean linear-time selection algorithm. A genuinely surprising idea: giving up exactness buys constant-time priority queue operations.
See also: Binary Heap · Exotic Structures · Dijkstra