Algorithm Search⌘K

Proofs: Relaxed heap

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

The relaxed heap of this page keeps the binomial shape and invariants (a) to (c), and FIX ends full

This proof shows: correctness.

We use the definitions of the page. A non-root node vv is a violation if v.key<p.keyv.key < p.key for its parent pp. A stale mark is a mark on a node that is not a violation. The invariants are (S) every node of rank kk has children of the ranks 0,…,k−10, \ldots, k - 1 in the slots 0,…,k−10, \ldots, k - 1, the parent pointers agree with the slots, the roots have different ranks and are not active, and the table of active nodes holds exactly the active nodes under their current ranks; (a) at most one active node of each rank; (b) every active node is a last child; (c) every non-root node that is not active is not a violation.

Lemma 1 (links). Let aa and bb be roots of equal rank kk that are not active and are not in any tree. LINK(a,b)(a, b) returns a tree of rank k+1k + 1 that satisfies (S). The loser is not active and not a violation. The only node whose last-child status changes, other than the loser, is the old last child of the winner, and the code pushes it on WW.

Proof. Say a.key≤b.keya.key \le b.key. Then bb becomes the child of slot kk of aa, and aa has the children of the ranks 0,…,k0, \ldots, k. The code removes the mark of bb, and b.key≥a.keyb.key \ge a.key. The children of bb keep their parent. The old child of rank k−1k - 1 of aa was the last child and is not any more; the code pushes it. The rank of aa changes, and the code moves aa in the table of active nodes if aa is active. □\square

Lemma 2 (shape). Every operation keeps (S), and every rank is at most ⌊lg⁡n⌋\lfloor \lg n \rfloor.

Proof. Look at each change of the trees. INSERT and the carries of delete-min only link roots of equal rank (Lemma 1) and put the result in the root table, carrying while the rank is taken, as in a binary counter. PARENT(s)(s): ss is the last child of pp, so r(s)=r(p)−1r(s) = r(p) - 1. After the cut r(p)=r(s)r(p) = r(s), so the link of pp under ss gives ss the rank r(s)+1r(s) + 1, which is the old rank of pp, and ss goes to the slot of pp. TRIPLE(v,s,c)(v, s, c): vv and cc have rank rr, and ss has rank r+1r + 1; after the cut ss has rank rr and goes to slot rr, and LINK(v,c)(v, c) has rank r+1r + 1 and goes to slot r+1r + 1. CLEAN exchanges two nodes of rank rr. PAIR(x,y)(x, y): pp and qq have rank r+1r + 1, since xx and yy are their last children of rank rr; after the cuts both have rank rr, qq goes to slot rr of pp, and LINK(x,y)(x, y) of rank r+1r + 1 goes to the old slot of qq. The parents differ, and neither of pp and qq is a descendant of the other, because a subtree of a node of rank r+1r + 1 holds only nodes of smaller rank below its root. So no cycle forms. In DELETE-MIN, if mm of rank rr is not a root after line L13, then tt has rank 0, and the links with the children of mm of the ranks 0,1,…,r−10, 1, \ldots, r - 1, in this order, give ranks 1,2,…,r1, 2, \ldots, r; the result fills slot rr of the parent of mm. If mm is a root, its children become roots. So the shape is always binomial. A binomial tree of rank kk has 2k2^k nodes by induction (2k=1+∑i<k2i2^k = 1 + \sum_{i < k} 2^i), so 2k≤n2^k \le n. Every move to the root table or a call of PLACE with no parent removes the mark, so roots are not active. Every change of the rank of a node goes through the helper that moves the node in the table of active nodes. □\square

Lemma 3 (heap order of the moves). No transformation and no link makes a node a violation, except the nodes that it pushes on WW.

Proof. We list the nodes that get a new parent or a new key. LINK: the loser is not a violation (Lemma 1). PARENT(s)(s) with s.key<p.keys.key < p.key: pp goes under ss, and p.key>s.keyp.key > s.key; ss gets the parent of pp and is pushed. TRIPLE: the condition of line L8 is false when line L9 runs, because either it was false for the first ss, or PARENT ran; in the second case PARENT either makes vv the last child of pp (when ss moves up, pp loses its last child ss and vv becomes the last child), or puts ss back with s.key≥p.keys.key \ge p.key. So s.key≥p.keys.key \ge p.key, and ss in the slot of vv is not a violation; it is pushed anyway. The tree LINK(v,c)(v, c) gets the parent pp and is pushed. CLEAN: cc is not active and c.key≥s.key≥p.keyc.key \ge s.key \ge p.key, so cc under pp is not a violation; vv under ss is pushed. PAIR: qq under pp has q.key≥p.keyq.key \ge p.key; LINK(x,y)(x, y) in the old place of qq is pushed. DELETE-MIN: the children of mm are linked under tt or under each other as losers, and the result is pushed. A decrease of the key of xx keeps the children of xx in order, and xx itself is pushed at line L4. □\square

Lemma 4 (the work list). At the top of the loop of FIX the following hold: (W1) every non-root node that is a violation and not active is on WW; (W2) every active node that is not a last child is on WW; (W3) for each rank rr, at most one active node of rank rr is not on WW. When WW is empty, (a), (b) and (c) hold.

Proof. When an operation calls FIX, (a), (b) and (c) held before the operation. The operation changes parents, slots, or the key of xx, and by Lemmas 1 and 3 it pushes every node whose parent, key or last-child status changed and that can be a violation or active. Line L13 makes children of tt roots, and roots satisfy all three properties. So (W1) to (W3) hold at the first test.

Now take one pass of the loop with the node vv. The nodes that the pass changes are vv, the nodes that a transformation moves, and the nodes whose last-child status changes; by Lemmas 1 and 3 all these are pushed, except the losers of links and the nodes put in place without a violation, and these are not active and not violations. So (W1) and (W2) can fail only for vv itself. Line L5: vv is a root or not a violation, and it becomes not active, so it breaks nothing. Lines L8 to L10 end the pass with vv pushed again (lines L8 and L10) or with vv not active, inside the pushed tree LINK(v,c)(v, c) (line L9), except when PARENT makes vv the last child; then the pass goes on to line L11 with vv active and a last child. At line L11, vv is an active last child. If no other active node has rank rr, then vv is the only active node of rank rr off WW, so (W3) holds. If another active node yy of rank rr exists and line L11 pushes vv and yy, then (W3) holds since vv is on WW. If PAIR runs, the marks of vv and yy go away, and by (W3) before the pass, at most one active node of rank rr was off WW other than vv; after the pass that is still true. A change of the rank of an active node happens only to a node that the same step pushes (the node ss of TRIPLE, the nodes pp of PARENT and PAIR, which lose their mark or get their old rank back), so it cannot break (W3).

If WW is empty, (W1) gives (c), (W2) gives (b), and (W3) gives (a). □\square

Lemma 5 (termination). FIX ends.

Proof. Let VV be the set of violations and define M=(∣V∣,−∑v∈Vr(v),N,Z)M = (|V|, -\sum_{v \in V} r(v), N, Z), where NN is the number of violations that are not last children and ZZ is the number of stale marks. Every component is a bounded integer, since ∣V∣≤n|V| \le n and all ranks are at most lg⁡n\lg n. Keys do not change in FIX, and a node changes its parent only in a transformation or a link. We show that each transformation lowers MM in lexicographic order.

  • PAIR: xx and yy are violations before. After, qq is under pp and not a violation, the loser of LINK(x,y)(x, y) is not a violation, and only the winner can be one. If qq was a violation, it is replaced by the winner. So ∣V∣|V| drops by at least 1.
  • TRIPLE: vv is a violation. If cc is a violation too, the two are replaced by at most the winner, so ∣V∣|V| drops. If cc has a stale mark, either the winner is not a violation and ∣V∣|V| drops, or vv of rank rr is replaced in VV by the winner of rank r+1r + 1, so the second component drops. The node ss is not a violation before or after.
  • PARENT(s)(s) with s.key<p.keys.key < p.key: ss is a violation before, and pp under ss is not after. If pp was a violation, ∣V∣|V| drops. Otherwise either ss is not a violation in the place of pp, and ∣V∣|V| drops, or ss stays in VV with the rank of pp, which is one larger, and the second component drops.
  • CLEAN: vv is a violation before and after, with the same rank; cc is not a violation before or after. vv was not a last child and now is, and no other node changes its last-child status in a way that matters: cc is not a violation. So NN drops. Line L5 removes a mark from a node that is not a violation, or does nothing, so ZZ drops or MM stays. Line L6 marks a violation, so ZZ does not change. So MM never grows in FIX, and it drops at each transformation. So there are finitely many transformations.

Between two transformations, MM does not grow, and passes that do not change MM are of three kinds: a pop that ends at line L5 with no change, a pop that ends at line L11 with nothing to do, and a pass that pushes two nodes at line L8 or line L11. A push at line L8 puts a violation ss of rank r+1r + 1 that is not a last child on top of WW. The next pass handles ss: it reaches line L7, and either a transformation runs or line L8 pushes a node of rank r+2r + 2. So a chain of such pushes has length at most lg⁡n\lg n and ends with a transformation. A push at line L11 puts yy on top. The next pass handles yy: either yy is not a violation, and line L5 removes its mark, which lowers ZZ; or yy is a violation that is not a last child, and then a chain as above ends with a transformation. So between two drops of MM there are at most O(log⁡n)O(\log n) pushes, and so O(log⁡n)+∣W∣O(\log n) + |W| passes. Since MM drops finitely often, FIX ends. □\square

Lemma 6 (find-min). When (c) holds, the smallest key is the key of a root or of an active node.

Proof. Take a node xx of smallest key. While the current node is not a root and not active, go to its parent; by (c) the key of the parent is at most the key of the node. The walk ends at a root or an active node, whose key is at most x.keyx.key, so it is also a smallest key. □\square

Theorem. After each operation, the heap holds exactly the inserted keys that were not deleted, with their current values, and (S), (a), (b), (c) hold; FIND-MIN and DELETE-MIN return a smallest key.

Proof. Lemma 2 gives (S), Lemma 5 that FIX ends, and Lemma 4 that (a), (b) and (c) hold when it ends. Insert adds one node. Decrease-key changes one key. Transformations and links only move nodes. In DELETE-MIN the node mm is removed from the trees: if mm is not a root, it is not in the tree of rank rr that fills its slot, and tt is in that tree; if mm becomes a root, it is removed from the root table and tt is added back. So exactly mm leaves, and mm has a smallest key by Lemma 6, applied to the state before the operation, when (c) held. The returned key was saved before the change. ■\blacksquare

Back to Relaxed heap