Algorithm Search⌘K

Proofs: Min-max heap

These are the human proofs of Min-max heap, at full length.

The operations of a min-max heap keep the min-max order full

This proof shows: correctness.

Call a pair (u,w)(u, w) of nodes, with uu a proper ancestor of ww, good if A[u]≤A[w]A[u] \le A[w] when uu is a min node and A[u]≥A[w]A[u] \ge A[w] when uu is a max node. The heap is in min-max order if every pair is good. For a node ii, write T(i)T(i) for its subtree, and say that x⪯iyx \preceq_i y if x≤yx \le y when ii is a min node and x≥yx \ge y when ii is a max node. "Better for the level of ii" means ≺i\prec_i, the strict form.

Lemma 0 (answers). In min-max order, A[0]A[0] is a smallest key; a largest key is A[0]A[0] if n=1n = 1, A[1]A[1] if n=2n = 2, and the larger of A[1]A[1] and A[2]A[2] if n≥3n \ge 3.

Proof. The root is a min node and an ancestor of all other nodes. Nodes 1 and 2 are max nodes, and every node other than the root is in T(1)T(1) or T(2)T(2). □\square

Lemma 1 (best candidate). Let ii have a child, and let every pair inside T(i)T(i) whose upper node is not ii be good. Let mm be a child or grandchild of ii with the ⪯i\preceq_i-best key among them. Then A[m]⪯iA[w]A[m] \preceq_i A[w] for every ww in T(i)T(i) other than ii.

Proof. Say ii is a min node; the other case is the same with the order reversed. The children of ii are max nodes and its grandchildren are min nodes. A node w≠iw \ne i of T(i)T(i) is a child or a grandchild of ii, so A[m]≤A[w]A[m] \le A[w] by the choice of mm, or it is a proper descendant of a grandchild gg, so A[w]≥A[g]≥A[m]A[w] \ge A[g] \ge A[m] because (g,w)(g, w) is good. □\square

Lemma 2 (PUSH-DOWN). If every pair inside T(i)T(i) whose upper node is not ii is good, then after PUSH-DOWN(A,i,n)\mathrm{PUSH\text{-}DOWN}(A, i, n) every pair inside T(i)T(i) is good, and the keys of T(i)T(i) are permuted among its nodes.

Proof. By induction on the height of ii. All changes are swaps inside T(i)T(i), so the keys are permuted. If ii has no child, there is no pair to check. Let ii be a min node; the max case is symmetric. Let xx be the key at ii at the start, and let mm be chosen at line L2. By Lemma 1, A[m]A[m] is a smallest key of T(i)T(i) other than xx.

Case 1: mm is a child (lines L3 to L5). If x≤A[m]x \le A[m], then xx is at most every key of T(i)T(i), and every pair (i,w)(i, w) is good. Otherwise the keys swap. Now A[i]A[i] is the old A[m]A[m], a smallest key of T(i)T(i), so the pairs (i,w)(i, w) are good. The node mm now holds x>A[m]oldx > A[m]_{\mathrm{old}}. Its descendants ww are grandchildren of ii or below them, so A[w]≥A[m]oldA[w] \ge A[m]_{\mathrm{old}} by Lemma 1, and A[w]≤A[m]oldA[w] \le A[m]_{\mathrm{old}} because (m,w)(m, w) was good. So all of them equal A[m]old<xA[m]_{\mathrm{old}} < x, and the pairs (m,w)(m, w), which need x≥A[w]x \ge A[w], are good. No other pair changed.

Case 2: mm is a grandchild and A[m]≥xA[m] \ge x (line L6). Then xx is at most every key of T(i)T(i), and all pairs are good.

Case 3: mm is a grandchild and A[m]<xA[m] < x (lines L7 to L9). After line L7, A[i]=yA[i] = y, the old A[m]A[m], which is a smallest key of T(i)T(i), so the pairs (i,w)(i, w) are good, also after the later steps, since they only permute keys of T(m)∪{p}T(m) \cup \{p\}. Let pp be the parent of mm, a max node, and let zz be its key. Before line L8, z≥z \ge every old key of T(p)T(p), because those pairs were good. If x>zx > z, line L8 swaps, so pp holds xx, which is larger than every other key now in T(p)T(p): those are zz and old keys of T(p)T(p). If x≤zx \le z, pp keeps zz, which is at least xx and every old key of T(p)T(p). Either way, every pair (p,w)(p, w) is good now and remains good, since the recursion only permutes the keys in T(m)T(m). Pairs whose upper node is in T(i)T(i) but not in T(m)∪{i,p}T(m) \cup \{i, p\} did not change. So the only pairs that may be bad have their upper node at mm, and the loop continues with i←mi \leftarrow m. By induction, it makes all pairs inside T(m)T(m) good. □\square

Lemma 3 (PUSH-UP). If every pair not involving the leaf ii is good, then after PUSH-UP(A,i)\mathrm{PUSH\text{-}UP}(A, i) every pair is good.

Proof. Let xx be the key at ii. If i=0i = 0 there is nothing to prove. Let pp be the parent of ii. Say ii is a min node and pp a max node; the other case is symmetric. Note that the ancestors of ii alternate between max nodes (pp, its grandparent, and so on) and min nodes.

If x>A[p]x > A[p] (line L12 true). Line L13 swaps. The leaf ii now holds z=A[p]oldz = A[p]_{\mathrm{old}}. All pairs (u,i)(u, i) are good: u=pu = p now holds x>zx > z; the other ancestors uu of ii are ancestors of pp, and (u,p)(u, p) was good for zz. Now xx is at pp. The pairs (p,w)(p, w) are good, because every key of T(p)T(p) other than xx was at most z<xz < x. A min ancestor uu of pp satisfies A[u]≤z<xA[u] \le z < x. Only the pairs (u,p)(u, p) with uu a max ancestor of pp may be bad, and these uu are the grandparent chain of pp. Lines L14 and L15 move xx up this chain while it is larger than the next grandparent gg. Each swap puts the key A[g]A[g], which was at least every key below gg, at the position of xx below it; so the pairs below the new place of A[g]A[g] stay good, and the min node between them holds a key at most A[g]A[g], since it was below gg. When the loop stops, xx is at most its next max ancestor and so at most all of them, and it is larger than all keys below it and than its min ancestors, by the same argument as for pp. All pairs are good.

If x≤A[p]x \le A[p] (line L12 false). Every max ancestor uu of ii is pp or an ancestor of pp, so A[u]≥A[p]≥xA[u] \ge A[p] \ge x, and these pairs are good. Only the pairs (u,i)(u, i) with uu a min ancestor may be bad, and these uu are the grandparent chain of ii. Lines L14 and L15 move xx up this chain while it is smaller than the next grandparent, with the same argument as above, and the order reversed. □\square

Theorem. INSERT, DELETE-MIN, DELETE-MAX and the build keep min-max order, and find-min, find-max, DELETE-MIN and DELETE-MAX return correct keys.

Proof. Insert. Before line L20, all pairs are good; the new leaf adds only pairs that involve it, so Lemma 3 applies.

Delete-min. By Lemma 0, A[0]A[0] is a smallest key. After the last key moves to the root, every pair whose upper node is not the root is a pair of the old heap, so it is good. Lemma 2 at i=0i = 0 makes all pairs good.

Delete-max. By Lemma 0, line L18 finds a largest key. If mm is the last cell, removing it removes only pairs. Otherwise the last key yy moves to m∈{0,1,2}m \in \{0, 1, 2\}. If m=0m = 0, then n=1n = 1 before the delete and nothing remains. If m∈{1,2}m \in \{1, 2\}, the only pair with upper node outside T(m)T(m) that involves mm is (0,m)(0, m), and A[0]≤yA[0] \le y because the root was a smallest key. Inside T(m)T(m), all pairs with upper node other than mm are old pairs. Lemma 2 at mm makes all pairs inside T(m)T(m) good, and pairs (0,w)(0, w) stay good since T(m)T(m) only permutes its keys.

Build. By induction on the steps: when PUSH-DOWN runs at ii, the nodes with a larger index have already been processed, or are leaves, so the subtrees of the children of ii are in order, and every pair inside T(i)T(i) whose upper node is not ii is good. Lemma 2 makes T(i)T(i) in order. After i=0i = 0, the whole heap is in order.

Find-min and find-max are correct by Lemma 0. ■\blacksquare

Back to Min-max heap