一、为什么学左偏树?
Mermaid · 渲染中(下方为源码)
graph LR A[可并堆] --> B[左偏树 merge O(log n)] B --> C[右链短, 沿右合并]
左偏树是支持高效**合并(merge)**的堆,解决二叉堆 merge 慢的问题:
| 操作 | 左偏树 | 二叉堆 |
|---|---|---|
| merge | O(log n) | O(n) |
| insert / extract-min | O(log n) | O(log n) |
应用:多路归并、可撤销贪心、Dijkstra 多源合并。
二、核心:dist(零路径长)
dist(x) = 从 x 到最近空子节点的距离。左偏性质:
任一节点的左孩子 dist ≥ 右孩子 dist(始终让右链更短)。
合并时把较矮的右孩子接上去,若破坏左偏则交换左右子树。
三、实现
class Node { int val, dist; Node l, r; }
int dist(Node x) { return x == null ? -1 : x.dist; }
Node merge(Node a, Node b) {
if (a == null) return b;
if (b == null) return a;
if (a.val > b.val) { Node t = a; a = b; b = t; } // 小根堆
a.r = merge(a.r, b);
if (dist(a.l) < dist(a.r)) { Node t = a.l; a.l = a.r; a.r = t; }
a.dist = dist(a.r) + 1;
return a;
}
Node insert(Node h, int v) { return merge(h, new Node(v)); }
Node extractMin(Node h) { return merge(h.l, h.r); }