Algorithm Search⌘K

Proofs: Rank-pairing heap

These are the human proofs of Rank-pairing heap, at full length.

Amortized cost of the type-2 rank-pairing heap full

This proof shows: time.amortized.

We prove Theorem 6.1 of Haeupler, Sen and Tarjan for type-2 rank-pairing heaps with multipass linking: find-min, insert, meld and decrease-key take O(1)O(1) amortized time, and delete-min takes O(log⁡n)O(\log n) amortized time. The proof follows the paper, with the accounting written out.

The rank bound. A child of rank kk has at least Fk+3−1F_{k+3} - 1 nodes in its subtree, with F0=0F_0 = 0, F1=1F_1 = 1. By induction on height: a missing node of rank −1-1 has 0=F2−10 = F_2 - 1 nodes, and a leaf has 1=F3−11 = F_3 - 1. A 0,ii-node of rank kk has a child of rank kk, and so at least Fk+3−1F_{k+3} - 1 nodes. A 1,1- or 1,2-node of rank kk has children of ranks at least k−1k - 1 and k−2k - 2, so at least 1+(Fk+2−1)+(Fk+1−1)=Fk+3−11 + (F_{k+2} - 1) + (F_{k+1} - 1) = F_{k+3} - 1 nodes. A root of rank kk has a left child of rank k−1k - 1, so its half tree has at least Fk+2≥φkF_{k+2} \ge \varphi^k nodes. So every rank is at most log⁡φn\log_\varphi n.

The potential. For a node xx, let σ(x)\sigma(x) be the sum of the rank differences of its children, where a missing child counts with its rank −1-1, but the missing right child of a root does not count. Let ψ(x)=σ(x)−1\psi(x) = \sigma(x) - 1 for every node. For a root, σ(x)=1\sigma(x) = 1 and ψ(x)=0\psi(x) = 0. Define the potential of a node as ϕ(x)=1\phi(x) = 1 for a root, ϕ(x)=0\phi(x) = 0 for a 1,1-node, and ϕ(x)=σ(x)−1\phi(x) = \sigma(x) - 1 for every other non-root. This is the potential of the paper: a root with a 1-child has potential 1, a 1,1-node has 0, and an i,ji,j-node other than a 1,1-node has i+j−1i + j - 1. Every ϕ(x)≥0\phi(x) \ge 0: a 1,2-node has 2, and a 0,ii-node with i>1i > 1 has at least 1. Let Φ\Phi be the sum over all nodes. The empty heap has Φ=0\Phi = 0.

Count one unit of time for each operation, each half tree processed in delete-min, each link and each iteration of the rank-reduction loop.

Insert, meld, find-min. Insert adds a root, ΔΦ=1\Delta\Phi = 1, so the amortized cost is 2. Meld and find-min do not change Φ\Phi.

Delete-min. Deleting the root zz lowers Φ\Phi by 1. The disassembly makes each node on the right spine of z.leftz.left a root, with ϕ=1\phi = 1. Each spine node that was not a 1,1-node had ϕ≥1\phi \ge 1, and its children do not change, so its potential does not increase. For a 1,1-node ss on the spine, its right child, the next spine node, has rank r(s)−1r(s) - 1. Ranks along the spine never increase, because rank differences are not negative. So the 1,1-nodes on the spine have distinct ranks, all less than r(z)≤log⁡φnr(z) \le \log_\varphi n, and there are at most log⁡φn\log_\varphi n of them. The disassembly raises Φ\Phi by at most log⁡φn\log_\varphi n.

Let hh be the number of half trees after the disassembly. The rest of the operation takes h+O(1)h + O(1) units plus one per link. Each link turns a root (ϕ=1\phi = 1) into a 1,1-node (ϕ=0\phi = 0) and does not change the children of any other node, except that the winner gets a new left child. The winner is a root, with ϕ=1\phi = 1 before and after. So each link lowers Φ\Phi by 1, which pays for the link. After multipass linking, the roots have distinct ranks in {0,…,⌊log⁡φn⌋}\{0, \ldots, \lfloor \log_\varphi n \rfloor\}, so at most log⁡φn+1\log_\varphi n + 1 remain, and there were at least h−log⁡φn−1h - \log_\varphi n - 1 links. The amortized cost is at most

h+O(1)+log⁡φn−(h−log⁡φn−1)=2log⁡φn+O(1).h + O(1) + \log_\varphi n - (h - \log_\varphi n - 1) = 2 \log_\varphi n + O(1).

Decrease-key. If xx is a root, the cost is 1 and Φ\Phi does not change. Otherwise let u1=uu_1 = u be the parent of xx, let yy be its right child, and let u1,u2,…,umu_1, u_2, \ldots, u_m be the non-roots whose ranks decrease, in this order; ui+1u_{i+1} is the parent of uiu_i. Let δi≥1\delta_i \ge 1 be the decrease at uiu_i, and let ww be the node at which the loop ends (a non-root whose rank does not change, or a root).

Claim A: at most one of u1,…,umu_1, \ldots, u_m is a 1,1-node before the operation, and every δi\delta_i after the first 1,1-node among them is 1. A 1,1-node of rank kk has children of rank k−1k - 1; if one of them loses rank, ff gives kk (if the child has rank k−2k - 2) or k−1k - 1 (if less), so a 1,1-node decreases by at most 1. By Lemma 2 of the correctness proof, a node whose child decreased by 1 decreases by at most 1. So once a 1,1-node tt decreases, every later decrease is by exactly 1. A later 1,1-node whose child decreases by exactly 1 has children of ranks k−1k - 1 and k−2k - 2, so f=kf = k and it does not decrease. So it is ww, not one of the uiu_i.

Accounting. Let Ψ=∑xψ(x)\Psi = \sum_x \psi(x) over all nodes, where ψ(x)=σ(x)−1\psi(x) = \sigma(x) - 1 for every node, root or not. Let NN be the number of 1,1-nodes. Since ϕ(x)=ψ(x)\phi(x) = \psi(x) for all nodes except 1,1-nodes and roots, and ϕ=ψ−1\phi = \psi - 1 for a 1,1-node and ϕ=ψ+1\phi = \psi + 1 for a root, we have Φ=Ψ−N+R\Phi = \Psi - N + R, where RR is the number of roots.

  • ΔR=+1\Delta R = +1 (the root xx).
  • −ΔN-\Delta N is at most the number of nodes that stop being 1,1-nodes. Only nodes whose children's rank differences change can change type: xx, the uiu_i, and ww. By Claim A at most one uiu_i is a 1,1-node. So −ΔN≤3-\Delta N \le 3.
  • ΔΨ\Delta\Psi. Before, ψ(x)=Δ(x.left)+Δ(y)−1\psi(x) = \Delta(x.left) + \Delta(y) - 1, where Δ(y)=r(x)−r(y)\Delta(y) = r(x) - r(y); after, xx is a root, with ψ(x)=0\psi(x) = 0. When yy replaces xx as a child of u1u_1, the rank difference of that child of u1u_1 grows from Δ(x)\Delta(x) to Δ(x)+Δ(y)\Delta(x) + \Delta(y), so ψ(u1)\psi(u_1) grows by Δ(y)\Delta(y). When the rank of uiu_i drops by δi\delta_i, the rank differences of both its children drop by δi\delta_i, so ψ(ui)\psi(u_i) drops by 2δi2\delta_i, and the rank difference of uiu_i as a child of ui+1u_{i+1} (or of ww) grows by δi\delta_i, which raises ψ\psi of the parent by δi\delta_i. If ww is a root, its rank is reset to make it a 1-node, so ψ(w)=0\psi(w) = 0 before and after the operation. Adding up,
ΔΨ≤1−Δ(x.left)−Δ(y)+Δ(y)−∑i=1m2δi+∑i=1mδi≤1−m,\Delta\Psi \le 1 - \Delta(x.left) - \Delta(y) + \Delta(y) - \sum_{i=1}^{m} 2\delta_i + \sum_{i=1}^{m} \delta_i \le 1 - m,

because Δ(x.left)≥0\Delta(x.left) \ge 0 and every δi≥1\delta_i \ge 1.

So ΔΦ≤(1−m)+3+1=5−m\Delta\Phi \le (1 - m) + 3 + 1 = 5 - m. The actual cost is 1 for the cut and m+1m + 1 for the iterations of the loop. The amortized cost of decrease-key is at most (m+2)+(5−m)=7(m + 2) + (5 - m) = 7, which is O(1)O(1). ■\blacksquare

The rank-pairing heap operations keep half order and the type-2 rank rule full

This proof shows: correctness.

We use the definitions of the page. A missing child has rank −1-1. For integers aa and bb, let f(a,b)=max⁡(a,b)f(a, b) = \max(a, b) if ∣a−b∣>1|a - b| > 1 and f(a,b)=max⁡(a,b)+1f(a, b) = \max(a, b) + 1 if ∣a−b∣≤1|a - b| \le 1. The invariants are (1) half order: the key of each node is at most every key in its left subtree, and every root has no right child; (2) the type-2 rank rule: every root xx has r(x)=r(x.left)+1r(x) = r(x.left) + 1, and every non-root is a 1,1-, 1,2- or 0,ii-node with i>1i > 1.

Lemma 1 (the rule fixes the rank). A non-root uu with children of ranks aa and bb obeys the type-2 rule if and only if r(u)=f(a,b)r(u) = f(a, b).

Proof. Let a≥ba \ge b. If r(u)=a+1r(u) = a + 1 and a−b≤1a - b \le 1, the rank differences are 11 and 11 or 11 and 22. If r(u)=ar(u) = a and a−b>1a - b > 1, they are 00 and a−b>1a - b > 1. Conversely, a 1,1- or 1,2-node has r(u)=a+1r(u) = a + 1 with a−b∈{0,1}a - b \in \{0, 1\}, and a 0,ii-node with i>1i > 1 has r(u)=ar(u) = a with a−b=i>1a - b = i > 1. In each case r(u)=f(a,b)r(u) = f(a, b). □\square

Lemma 2 (monotone). ff does not decrease when one argument increases by one, and it increases by at most one.

Proof. Fix bb and compare f(a,b)f(a, b) with f(a+1,b)f(a + 1, b). If a+1≤b−2a + 1 \le b - 2, both are bb. If a+1=b−1a + 1 = b - 1, they are bb and b+1b + 1. If a+1∈{b,b+1}a + 1 \in \{b, b + 1\}, they are b+1b + 1 and b+1b + 1 when a+1=ba + 1 = b, and b+1b + 1 and b+2b + 2 when a+1=b+1a + 1 = b + 1. If a≥b+1a \ge b + 1, then a+1≥b+2a + 1 \ge b + 2, so f(a+1,b)=a+1f(a + 1, b) = a + 1, and f(a,b)∈{a,a+1}f(a, b) \in \{a, a + 1\}. In every case the increase is 0 or 1. The function is symmetric. □\square

Lemma 3 (link). If xx and yy are roots of half trees of equal rank kk that satisfy (1) and (2), LINK(x,y)(x, y) returns the root of a half tree of rank k+1k + 1 that satisfies (1) and (2).

Proof. After line L1, x.key≤y.keyx.key \le y.key. The new left subtree of xx holds yy, the left subtree of yy, and the old left subtree of xx. Every key there is at least x.keyx.key: the first two because y.key≥x.keyy.key \ge x.key and by half order at yy, the third by half order at xx. The left subtree of yy did not change. The ranks of the two children of yy are r(y.left)=k−1r(y.left) = k - 1 and r(old x.left)=k−1r(\text{old } x.left) = k - 1, so yy is a 1,1-node. The root xx now has rank k+1=r(y)+1k + 1 = r(y) + 1, so it is a 1-node and has no right child. □\square

Theorem 1 (insert, meld, delete-min). These operations keep (1) and (2), and delete-min returns a smallest key.

Proof. Insert adds a one-node half tree of rank 0=−1+10 = -1 + 1. Meld only joins root lists. In delete-min, each root holds the smallest key of its half tree, because the root has no right child and its left subtree holds all other nodes, so z=H.minz = H.min holds a smallest key. Line L4 removes zz and cuts the right spine s1=z.left,s2=s1.right,…s_1 = z.left, s_2 = s_1.right, \ldots. Each sis_i keeps its left subtree, so half order holds in the new half tree rooted at sis_i, which has no right child, and r(si)=r(si.left)+1r(s_i) = r(s_i.left) + 1 makes it a 1-node. Nodes inside the left subtrees do not change. The links of lines L5 and L6 join only half trees of equal rank, so they keep (1) and (2) by Lemma 3. □\square

Theorem 2 (decrease-key). DECREASE-KEY keeps (1) and (2).

Proof. If xx is a root, its key is at most every key in its left subtree before the change, and so also after it. Otherwise let uu be the parent of xx and yy its right child.

Half order after line L9. Let vv be any node other than xx. If xx was in the left subtree of vv, then so were yy and its subtree; after line L9 the left subtree of vv is the old one without xx and the left subtree of xx. So it lost keys and gained none, and half order at vv holds. Otherwise the left subtree of vv did not change. At xx, every key of its left subtree was at least the old key of xx, which is at least the new key. So half order holds everywhere, and xx is a root with no right child.

The rank rule. Line L9 sets r(x)=r(x.left)+1r(x) = r(x.left) + 1, so the new root is a 1-node. The nodes in the subtrees of x.leftx.left and yy did not change. The only node whose children changed is uu: its child xx, of rank r(x)r(x), was replaced by yy, of rank r(y)≤r(x)r(y) \le r(x), because rank differences are not negative. We prove by induction over the iterations of lines L10 to L14 this claim: at the start of an iteration with node uu, every node other than uu obeys the rule, and the ranks of the children of uu are at most what they were when uu last obeyed the rule.

If uu is a root, line L11 makes it a 1-node, and the rule holds everywhere. Otherwise let k=f(r(u.left),r(u.right))k = f(r(u.left), r(u.right)). When uu last obeyed the rule, r(u)r(u) was ff of the old ranks of its children, by Lemma 1. The rank of uu has not changed since then, and by Lemma 2 ff does not increase when the arguments decrease, so k≤r(u)k \le r(u). If k=r(u)k = r(u), line L13 returns, and uu obeys the rule by Lemma 1. If k<r(u)k < r(u), line L14 sets r(u)=kr(u) = k, so uu obeys the rule. Its parent now has a child of smaller rank, and every other node obeys the rule, so the claim holds for the next iteration with the parent of uu. Each iteration goes one level up, so the loop ends, at a root or at line L13. ■\blacksquare

Back to Rank-pairing heap