Algorithm Search⌘K

Proofs: Interval heap

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

The interval heap operations keep the interval invariants full

This proof shows: correctness, termination.

We use the notation of the page: the node jj has the low key LO(j)=A[2j]\mathrm{LO}(j) = A[2j] and the high key HI(j)\mathrm{HI}(j), which is A[2j+1]A[2j + 1] if it exists and A[2j]A[2j] else; P(j)=⌊(j−1)/2⌋P(j) = \lfloor (j - 1)/2 \rfloor. The invariants are (N) LO(j)≤HI(j)\mathrm{LO}(j) \le \mathrm{HI}(j), and (I) LO(P(j))≤LO(j)\mathrm{LO}(P(j)) \le \mathrm{LO}(j) and HI(j)≤HI(P(j))\mathrm{HI}(j) \le \mathrm{HI}(P(j)) for j≥1j \ge 1. For an edge (P(j),j)(P(j), j), call the first inequality of (I) its low side and the second its high side.

Lemma 0. If (N) and (I) hold, then every key lies in [A[0],HI(0)][A[0], \mathrm{HI}(0)]. So FIND-MIN and FIND-MAX are correct.

Proof. By induction on the depth of a node jj: its keys lie in [LO(j),HI(j)][\mathrm{LO}(j), \mathrm{HI}(j)] by (N), and by (I) this interval lies inside the interval of P(j)P(j). □\square

Lemma 1 (sift-up on the low side). Let tt be the last node, and suppose that (N) holds, that (I) holds except perhaps on the low side of the edge into tt, and that t≥1t \ge 1 implies LO(t)≤HI(P(t))\mathrm{LO}(t) \le \mathrm{HI}(P(t)). Then SIFT-UP-MIN(t)(t) stops after at most ⌊lg⁡(t+1)⌋\lfloor \lg(t + 1) \rfloor iterations, and after it (N) and (I) hold.

Proof. We show that before each test of line L4, for the current node jj:

(U) (N) holds; (I) holds except perhaps on the low side of the edge into jj; and if j≥1j \ge 1, then LO(j)≤HI(P(j))\mathrm{LO}(j) \le \mathrm{HI}(P(j)), LO(P(j))≤LO(c)\mathrm{LO}(P(j)) \le \mathrm{LO}(c) for each child cc of jj, and either jj holds one key or LO(P(j))≤HI(j)\mathrm{LO}(P(j)) \le \mathrm{HI}(j).

Start. j=tj = t is the last node, so it has no children. If it holds two keys, one of them is the old key ww of the node, which lay in the interval of P(t)P(t) before the insert, and HI(t)\mathrm{HI}(t) is the larger of the two keys, so HI(t)≥w≥LO(P(t))\mathrm{HI}(t) \ge w \ge \mathrm{LO}(P(t)). The rest is the hypothesis.

Step. Let the test be true, with q=P(j)q = P(j), y=LO(j)y = \mathrm{LO}(j) and z=LO(q)z = \mathrm{LO}(q), so y<zy < z. Line L5 swaps yy and zz.

  • (N) at qq: the new LO(q)=y<z≤HI(q)\mathrm{LO}(q) = y < z \le \mathrm{HI}(q).
  • (N) at jj: if jj holds one key, it is zz, and there is nothing to show. Else HI(j)≥z\mathrm{HI}(j) \ge z by the last part of (U).
  • The low side of (q,j)(q, j): y<zy < z. The low side of (q,s)(q, s) for the other child ss of qq: it held with zz, so LO(s)≥z>y\mathrm{LO}(s) \ge z > y.
  • The low sides of (j,c)(j, c) for the children cc of jj: LO(c)≥LO(q)old=z\mathrm{LO}(c) \ge \mathrm{LO}(q)_{\text{old}} = z by (U).
  • The high sides: no high key moved, except that a single-key node jj now has HI(j)=z≤HI(q)\mathrm{HI}(j) = z \le \mathrm{HI}(q).

So (N) holds, and (I) holds except perhaps on the low side of the edge into qq. For the rest of (U) at the new j=q≥1j = q \ge 1: LO(q)=y<z≤HI(q)≤HI(P(q))\mathrm{LO}(q) = y < z \le \mathrm{HI}(q) \le \mathrm{HI}(P(q)); the children of qq have low keys zz and LO(s)\mathrm{LO}(s), and the old low side of the edge into qq gives LO(P(q))≤z≤LO(s)\mathrm{LO}(P(q)) \le z \le \mathrm{LO}(s); and qq holds two keys, since it is not the last node, with HI(q)≥z≥LO(P(q))\mathrm{HI}(q) \ge z \ge \mathrm{LO}(P(q)).

End. Each iteration moves to the parent, so there are at most ⌊lg⁡(t+1)⌋\lfloor \lg(t + 1) \rfloor iterations. When the test is false, either j=0j = 0, which has no edge into it, or the low side of the edge into jj holds. With (U), (N) and (I) hold. □\square

Lemma 1'. The mirror statement holds for SIFT-UP-MAX on the high side, with the same proof and the order reversed.

INSERT. Before line L1 the invariants hold. Let xx be the new key and jj the last node.

Line L2 orders the pair of jj if it has two keys, so (N) holds. The old key ww of jj, if any, lay in [LO(P(j)),HI(P(j))][\mathrm{LO}(P(j)), \mathrm{HI}(P(j))] by (I). The node jj has no children. So (I) can fail only at the edge (P(j),j)(P(j), j), and only through xx: if x<LO(P(j))x < \mathrm{LO}(P(j)), then xx is now LO(j)\mathrm{LO}(j) and only the low side fails, and x<LO(P(j))≤HI(P(j))x < \mathrm{LO}(P(j)) \le \mathrm{HI}(P(j)); if x>HI(P(j))x > \mathrm{HI}(P(j)), then xx is now HI(j)\mathrm{HI}(j) and only the high side fails; else nothing fails.

In the first case, Lemma 1 applies to SIFT-UP-MIN(j)(j), and afterwards (N) and (I) hold, so SIFT-UP-MAX(j)(j) finds its test false at once, because each edge holds. The second case is symmetric with Lemma 1'. In the third case both sifts stop at once.

EXTRACT-MIN. By Lemma 0, r=A[0]r = A[0] is a smallest key. If n=1n = 1, the queue becomes empty. Else the last key xx is removed and written to A[0]A[0]. Removing the last key keeps (N) and (I) for all other nodes, since it deletes the high key of the last node or the whole last node; a node with one key left has LO=HI\mathrm{LO} = \mathrm{HI}, and its key still lies in the parent's interval. The new xx is at most HI(0)\mathrm{HI}(0) by Lemma 0, so (N) holds at the root.

The claim before each test of line L11, for the current jj: (N) holds everywhere; (I) holds except perhaps on the low sides of the edges from jj to its children; and if j≥1j \ge 1, then LO(P(j))≤LO(c)\mathrm{LO}(P(j)) \le \mathrm{LO}(c) for each child cc of jj. At the start, j=0j = 0, and the last part is empty.

Let cc be the child with the smaller low key, and let the test of line L12 be true: LO(c)<LO(j)=x′\mathrm{LO}(c) < \mathrm{LO}(j) = x'. Line L13 swaps the two low keys. At jj, the new low key LO(c)old\mathrm{LO}(c)_{\text{old}} is at most the low key of the other child, so the low sides at jj hold; it is at least LO(P(j))\mathrm{LO}(P(j)) by the last part of the claim; and it is less than x′≤HI(j)x' \le \mathrm{HI}(j), so (N) holds at jj. At cc, the low slot now holds x′x'. The high side of (j,c)(j, c) still holds, since HI(c)\mathrm{HI}(c) did not move. If HI(c)<x′\mathrm{HI}(c) < x', line L13 swaps the two keys of cc, so cc holds (HI(c)old,x′)(\mathrm{HI}(c)_{\text{old}}, x'); then (N) holds at cc, and the high side of (j,c)(j, c) holds because x′≤HI(j)x' \le \mathrm{HI}(j), which was true before since x′x' was the low key of jj. The new low key of cc is at least LO(c)old\mathrm{LO}(c)_{\text{old}}, which is now LO(j)\mathrm{LO}(j), so the low side of (j,c)(j, c) holds. For the children dd of cc, LO(d)≥LO(c)old=LO(j)\mathrm{LO}(d) \ge \mathrm{LO}(c)_{\text{old}} = \mathrm{LO}(j), which is the last part of the claim at the new j=cj = c; their low sides may now fail, and their high sides held and HI(c)\mathrm{HI}(c) did not decrease. So the claim holds after line L14.

When the loop returns at line L11 or L12, the low sides at jj hold, so (N) and (I) hold. Each iteration moves one level down, so the loop stops after at most the height of the tree.

EXTRACT-MAX is the mirror image for n≥3n \ge 3. For n≤2n \le 2, the last key is the largest by (N), and removing it leaves a valid heap.

Theorem. Starting from the empty array, each sequence of INSERT, EXTRACT-MIN and EXTRACT-MAX keeps (N) and (I), each operation stops in O(log⁡n)O(\log n) steps, and the extracts and finds return a smallest or a largest key of the multiset. The array always holds exactly the current multiset.

Proof. The invariants and termination are the cases above, and the answers follow from Lemma 0. Each operation only appends, removes the last key, overwrites the removed extreme key with the removed last key, or swaps keys, so the multiset changes as the operation says. ■\blacksquare

Back to Interval heap