Algorithm Search⌘K

Proofs: Thin heap

These are the human proofs of Thin heap, at full length.

Amortized cost of the thin heap full

This proof shows: time.amortized.

We prove that insert, meld, find-min and decrease-key take O(1)O(1) amortized time and that delete-min takes O(log⁡n)O(\log n) amortized time, where nn is the number of items at the time of the operation.

Cost units. Count one unit for each operation, one unit for each root that delete-min puts into the buckets, one unit for each link, and one unit for each iteration of the loop of decrease-key. Every other step of an operation takes constant time per unit.

Potential. Let tt be the number of trees and hh the number of thin nodes, and let Φ=2t+4h\Phi = 2t + 4h. The empty heap has Φ=0\Phi = 0, and Φ≥0\Phi \ge 0 always, so the total actual cost of any sequence that starts from an empty heap is at most the total amortized cost.

Insert and meld. Insert has actual cost 1 and adds one tree, so its amortized cost is 1+2=31 + 2 = 3. Meld has actual cost 1 and does not change tt or hh of the union. Find-min has actual cost 1.

Decrease-key. If xx is a root, the actual cost is 1 and Φ\Phi does not change. Otherwise the cut at line L9 adds one tree, ΔΦ≤+2\Delta\Phi \le +2 (and −4-4 more if xx was thin). Consider the iterations of the loop.

  • An iteration that ends at line L14 cuts a thin node yy (a parent defect with r(y)−c=3r(y) - c = 3 means that yy was thin before the operation started the iteration, with first child of rank c+1=r(y)−2c + 1 = r(y) - 2) and makes it a normal root: Δt=+1\Delta t = +1, Δh=−1\Delta h = -1, ΔΦ=−2\Delta\Phi = -2. With the actual cost of 1, the amortized cost is −1-1.
  • An iteration at line L16 makes the thin node yy normal: ΔΦ=−4\Delta\Phi = -4, amortized −3-3.
  • The last iteration returns at line L12, L13 or L15. Line L12 changes only the rank of a root, which stays normal. Lines L13 and L15 make yy thin. So ΔΦ≤+4\Delta\Phi \le +4, and the amortized cost is at most 5.

So the amortized cost of decrease-key is at most 1+2+5=81 + 2 + 5 = 8.

Delete-min. Let tt be the number of trees before, let dd be the number of children of the minimum zz, and let t′t' be the number of trees after. Lemma 1 of the correctness proof gives d=r(z)≤log⁡φn+1d = r(z) \le \log_\varphi n + 1. The operation puts t−1+dt - 1 + d roots into the buckets, and each link removes one tree, so it makes ℓ=t−1+d−t′\ell = t - 1 + d - t' links. It may make thin children normal (line L4), and it makes no node thin, so Δh≤0\Delta h \le 0. The actual cost is 1+(t−1+d)+ℓ+t′1 + (t - 1 + d) + \ell + t', where the last term pays for building the new root list, and

amortized≤1+(t−1+d)+(t−1+d−t′)+t′+2(t′−t)=2d−1+2t′.\text{amortized} \le 1 + (t - 1 + d) + (t - 1 + d - t') + t' + 2(t' - t) = 2d - 1 + 2t'.

After the links, the roots have distinct ranks, all at most log⁡φn+1\log_\varphi n + 1 by Lemma 1, so t′≤log⁡φn+2t' \le \log_\varphi n + 2. The amortized cost is at most 4log⁡φn+5=O(log⁡n)4 \log_\varphi n + 5 = O(\log n). ■\blacksquare

The thin-heap operations keep the thin-heap invariants full

This proof shows: correctness.

We use the invariants of the page. (1) Heap order: each key is at least the key of its parent. (2) The children of each node xx, in list order, have the ranks c,c−1,…,0c, c - 1, \ldots, 0 for c=r(x)−1c = r(x) - 1 (xx normal) or c=r(x)−2c = r(x) - 2 (xx thin), where an empty list has c=−1c = -1. (3) Every root is normal. Write r(NIL)=−1r(\mathrm{NIL}) = -1.

Lemma 1 (rank bound). A node of rank kk has at least Fk+1F_{k+1} nodes in its subtree, where F1=F2=1F_1 = F_2 = 1 and Fj+2=Fj+1+FjF_{j+2} = F_{j+1} + F_j. So in a heap of nn items every rank is at most log⁡φn+1\log_\varphi n + 1.

Proof. By induction on kk. For k≤1k \le 1 the subtree has at least 1=Fk+11 = F_{k+1} node. For k≥2k \ge 2, by (2) the node has children of ranks at least k−2,k−3,…,0k - 2, k - 3, \ldots, 0, so by induction its subtree has at least 1+∑i=0k−2Fi+1=1+(Fk+1−1)=Fk+11 + \sum_{i=0}^{k-2} F_{i+1} = 1 + (F_{k+1} - 1) = F_{k+1} nodes, using ∑j=1mFj=Fm+2−1\sum_{j=1}^{m} F_j = F_{m+2} - 1. Since Fk+1≥φk−1F_{k+1} \ge \varphi^{k-1}, n≥φk−1n \ge \varphi^{k-1} and k≤log⁡φn+1k \le \log_\varphi n + 1. □\square

Lemma 2 (link). If xx and yy are normal roots of rank kk that satisfy (1) and (2) in their trees, LINK returns a normal root of rank k+1k + 1 whose tree satisfies (1) and (2).

Proof. Line L1 makes x.key≤y.keyx.key \le y.key, so heap order holds at the new edge. The children of xx had the ranks k−1,…,0k - 1, \ldots, 0; now yy, of rank kk, comes first, so they are k,k−1,…,0k, k - 1, \ldots, 0 and xx is normal with rank k+1k + 1. The node yy keeps its children and its rank, and it was normal. □\square

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

Proof. Insert adds a root of rank 0 with no child, which is normal. Meld only joins two lists of roots. In delete-min, the minimum root zz holds a smallest key: by heap order, every key is at least the key of its root, and H.minH.min is the smallest root. The children of zz become roots. A thin child cc gets the rank r(c.child)+1r(c.child) + 1 at line L4. This changes no child list, and it makes cc normal, so (2) and (3) hold for all roots. Heap order has no parent condition for a root. Lemma 2 shows that each link keeps (1) to (3). At the end the smallest root is found again. □\square

The defect of decrease-key. Say the heap has a sibling defect at yy if yy is not a root, (1) holds, and (2) and (3) hold except that the node after yy in its sibling list has rank r(y)−2r(y) - 2 (with rank −1-1 if yy is the last child). Say it has a parent defect at yy if (1) holds, and (2) and (3) hold except at yy, whose children have the ranks c,c−1,…,0c, c - 1, \ldots, 0 with r(y)−c∈{2,3}r(y) - c \in \{2, 3\}. A parent defect with r(y)−c=2r(y) - c = 2 is not a defect at all when yy is not a root: yy is then thin.

Lemma 3 (the hole left by a cut). Suppose (1) to (3) hold except for one defect that is not at uu or below uu, and let uu be a non-root node with rank ii and left neighbor yy, that is, its parent if uu is a first child and its left sibling otherwise. After uu and its subtree are cut out of the list and uu becomes a root with rank r(u.child)+1r(u.child) + 1, the heap has a sibling defect at yy if yy was the left sibling of uu, and a parent defect at yy if yy was the parent of uu. The subtree of uu satisfies (1) to (3).

Proof. The node after uu in the list had rank i−1i - 1, or uu was the last child and i=0i = 0. If yy is the left sibling, its rank is i+1i + 1, and after the cut its next node has rank i−1=r(y)−2i - 1 = r(y) - 2: a sibling defect. If yy is the parent, its first child had rank ii and r(y)∈{i+1,i+2}r(y) \in \{i + 1, i + 2\}; now the first child has rank c=i−1c = i - 1, so r(y)−c∈{2,3}r(y) - c \in \{2, 3\}: a parent defect. All other lists are unchanged. The new rank of uu makes it normal and does not change its children. Heap order inside the subtree of uu holds as before, and uu has no parent. □\square

Lemma 4 (one step of the loop). If the heap has a sibling or parent defect at yy before an iteration of lines L11 to L16, then after it either (1) to (3) hold, or there is a defect of one of the two kinds at the old left neighbor of yy.

Proof. Heap order is not changed by a change of rank. The only move of a node from one parent to another is line L15, which moves the first child ww of yy to be a sibling of yy, so the new parent of ww is the parent pp of yy, and w.key≥y.key≥p.keyw.key \ge y.key \ge p.key.

Parent defect, line L12. If yy is a root, setting r(y)=c+1r(y) = c + 1 makes yy normal, and as a root it has no sibling condition. All invariants hold.

Parent defect, line L13. If yy is not a root and r(y)=c+2r(y) = c + 2, then yy is thin, which (2) allows. The rank of yy did not change, so its own list position is correct. All invariants hold.

Parent defect, line L14. If r(y)=c+3r(y) = c + 3 and yy is not a root, line L14 cuts yy and makes it a normal root. By Lemma 3, applied with u=yu = y, the heap has a defect at the old left neighbor of yy.

Sibling defect, line L15. Let k=r(y)k = r(y). If yy is normal, its first child ww has rank k−1k - 1, and its next child has rank k−2k - 2. Line L15 moves ww right after yy. Now the list of yy's parent reads …,k,k−1,k−2,…\ldots, k, k - 1, k - 2, \ldots, which is correct, and the children of yy start at rank k−2k - 2, so yy is thin, which is allowed for a non-root. All invariants hold.

Sibling defect, line L16. If yy is thin, its first child has rank k−2k - 2. Line L16 sets r(y)=k−1r(y) = k - 1, so yy is normal, and its next node, of rank k−2k - 2, is now correct. In the list that holds yy, yy had rank kk and now has rank k−1k - 1. If yy has a left sibling zz, then r(z)=k+1=r(y)+2r(z) = k + 1 = r(y) + 2: a sibling defect at zz. If yy is a first child of zz, then the first child of zz now has rank k−1k - 1, one less than before, and r(z)−(k−1)∈{2,3}r(z) - (k - 1) \in \{2, 3\}: a parent defect at zz. □\square

Theorem 2 (decrease-key). DECREASE-KEY keeps (1) to (3), and the heap holds the same items with the new key at xx.

Proof. If xx is a root, lowering its key keeps heap order, because a root has no parent, and line L8 updates H.minH.min. Otherwise line L9 cuts xx. Inside its subtree, every key was at least the old key of xx, which is at least the new key, so heap order holds there, and xx is a root. By Lemma 3 there is now one defect at the old left neighbor yy. By Lemma 4, each iteration either removes the defect, and the procedure returns, or moves it to the left neighbor of yy. Moving to a left sibling or to a parent goes along a path that cannot repeat a node: each move increases the rank of the current node or goes up a level, and there are finitely many nodes. The move from a parent defect at a root always returns at line L12. So the loop ends, and when it ends, (1) to (3) hold. No node is removed or created. ■\blacksquare

Back to Thin heap