Algorithm Search⌘K

Proofs: Treap split

These are the human proofs of Treap split, at full length.

Treap split returns two treaps that partition the keys full

This proof shows: correctness.

A treap is a binary tree with (P1) the search order on keys and (P2) the max-heap order on priorities. Write K(t)K(t) for the set of keys of the subtree tt, and N(t)N(t) for its set of nodes.

Theorem. Let tt be a treap or nil and kk a key. Then SPLIT(t,k)(t, k) returns (L,R)(L, R), where LL and RR are treaps, K(L)={x∈K(t):x<k}K(L) = \{x \in K(t) : x < k\}, K(R)={x∈K(t):x≥k}K(R) = \{x \in K(t) : x \ge k\}, and N(L)∪N(R)=N(t)N(L) \cup N(R) = N(t). Each node keeps its key and priority.

Proof. By induction on the number of nodes of tt. If tt is nil, line L1 returns two empty trees, which is right.

Case t.key<kt.key < k (lines L2 to L5). Let l=t.leftl = t.left and r=t.rightr = t.right. Since t.rightt.right is a treap with fewer nodes, the induction hypothesis gives, at line L3, treaps AA and BB with N(A)∪N(B)=N(r)N(A) \cup N(B) = N(r), K(A)={x∈K(r):x<k}K(A) = \{x \in K(r) : x < k\} and K(B)={x∈K(r):x≥k}K(B) = \{x \in K(r) : x \ge k\}.

After line L4, tt has the left subtree ll and the right subtree AA. We check that this tree, LL, is a treap.

  • (P1) at tt: each key of ll is less than t.keyt.key, since ll is unchanged. Each key of AA is a key of rr, so it is greater than t.keyt.key. Inside ll and AA, (P1) holds since they are treaps.
  • (P2) at tt: the root of AA, if any, is a node of rr, and every node of rr has priority at most t.prit.pri, by (P2) in the old tt. The left child is unchanged. Inside ll and AA, (P2) holds.

Its keys are K(l)∪{t.key}∪K(A)K(l) \cup \{t.key\} \cup K(A). Every key of ll and t.keyt.key itself is less than kk, and K(A)K(A) is the set of keys of rr less than kk. Since K(t)=K(l)∪{t.key}∪K(r)K(t) = K(l) \cup \{t.key\} \cup K(r), the keys of LL are exactly the keys of tt less than kk. The tree R=BR = B is a treap whose keys are those of rr that are at least kk; the keys of ll and t.keyt.key are less than kk, so these are all the keys of tt at least kk. The nodes of LL and RR are N(l)∪{t}∪N(A)∪N(B)=N(t)N(l) \cup \{t\} \cup N(A) \cup N(B) = N(t).

Case t.key≥kt.key \ge k (lines L6 to L9). This is the mirror image: every key of t.rightt.right is greater than t.key≥kt.key \ge k, so tt and its right subtree belong in RR. By induction, line L7 splits ll into AA (keys less than kk) and BB (keys at least kk). After line L8, tt has the left subtree BB and the right subtree rr. The keys of BB come from ll, so they are less than t.keyt.key, and their priorities are at most t.prit.pri; so RR is a treap with the keys of tt at least kk, and L=AL = A is a treap with the keys of tt less than kk.

Termination and cost. Each call recurses on one child of tt, so the calls follow one path from the root down, and there are at most h+1h + 1 of them, where hh is the height of tt. Each does O(1)O(1) work. The visited nodes are the nodes on the search path of kk: at each node, the call goes right when the key is less than kk and left otherwise, as a search for kk would (with a key equal to kk treated as greater). ■\blacksquare

Back to Treap split