Algorithm Search⌘K

Proofs: Treap

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

Insertion and deletion keep the treap invariant 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: each node has a priority at least as high as those of its children. Write K(t)K(t) for the set of keys of the subtree tt. A rotation keeps the in-order sequence of the keys, so it keeps (P1) and the key set (see tree rotation). For the heap order we track bad edges: an edge from a parent yy to a child xx with x.pri>y.prix.pri > y.pri.

Insertion

Lemma 1. Let tt be a treap or nil, with k∉K(t)k \notin K(t). Then r=INSERT(t,k,p)r = \text{INSERT}(t, k, p) has the keys K(t)∪{k}K(t) \cup \{k\}, satisfies (P1), and has no bad edge. Moreover, its root is either the root of tt or the new node of key kk.

Proof. By induction on the size of tt. If tt is nil, line L1 returns one node. Else let k<t.keyk < t.key (the case k>t.keyk > t.key, with lines L4 and L5, is the mirror image). By induction, line L2 makes t.leftt.left a treap r′r' with the new key, with (P1), no bad edge, and root either the old left child ll of tt or the new node xx. Every key of r′r' is less than t.keyt.key, so the subtree of tt satisfies (P1). The only edge that can be bad is the edge from tt to the root of r′r'.

If the root of r′r' is ll, its priority is at most t.prit.pri by (P2) for the old tt, so there is no bad edge, line L3 does nothing, and the root is tt.

If the root of r′r' is xx and x.pri≤t.prix.pri \le t.pri, there is no bad edge and line L3 does nothing. If x.pri>t.prix.pri > t.pri, line L3 rotates right at tt. Now xx is the root, tt is its right child, and the old right child bb of xx becomes the left child of tt. Check every changed edge. The edge x→tx \to t is good, since x.pri>t.prix.pri > t.pri. The edge t→bt \to b is good: all nodes of r′r' other than xx are nodes of the old t.leftt.left, so each has priority at most t.prit.pri by (P2) for the old tree, and bb is one of them. The edge t→t.rightt \to t.right is unchanged and good, and the edge x→ax \to a to the left child of xx is unchanged and good. So there is no bad edge, and the root is the new node. □\square

So INSERT on a treap gives a treap with the new key. If kk is already in the tree, INSERT returns at line L6 with no change at the node of key kk and no rotation above it, since each child it returns is the same node as before.

Deletion

The heap order with one hole. Let xx be a node of a binary tree. Say that the tree has (P2) except at xx if every edge that does not touch xx is good, and, when xx has a parent yy, every child cc of xx has c.pri≤y.pric.pri \le y.pri. In words: if xx were removed and its children hung on its parent, the tree would be a heap. Then for any two nodes u≠xu \ne x and v≠xv \ne x with vv below uu, v.pri≤u.priv.pri \le u.pri: the path from uu to vv uses good edges, except that it may pass through xx, and the step from the parent of xx over xx to a child of xx does not increase the priority, by the definition. A treap has (P2) except at any of its nodes.

Lemma 2. Let tt have (P1) and (P2) except at xx, where x.key=kx.key = k. Then DELETE(t,k)(t, k) returns a treap with the keys K(t)∖{k}K(t) \setminus \{k\}, whose root, if any, is a node of tt other than xx.

Proof. By induction on the size of tt.

Case x≠tx \ne t (lines L8 and L9). The node xx is in the child cc on the side of kk, by (P1). The subtree cc has (P2) except at xx, so by induction DELETE(c,k)(c, k) returns a treap c′c' with keys K(c)∖{k}K(c) \setminus \{k\}, whose root vv is a node of cc other than xx. By the remark above, v.pri≤t.priv.pri \le t.pri, so the edge from tt to vv is good. The other child of tt and its edge are unchanged and good, so the subtree of tt is a treap. Its keys are K(t)∖{k}K(t) \setminus \{k\}, and (P1) holds because the keys of c′c' come from cc.

Case x=tx = t with at most one child (lines L10 and L11). The result is the other child, or nil. No edge in it touches xx, so it is a treap, and its keys are K(t)∖{k}K(t) \setminus \{k\}.

Case x=tx = t with two children a=t.lefta = t.left and b=t.rightb = t.right. Say a.pri>b.pria.pri > b.pri, which is line L12; line L13 is the mirror image and also covers ties. Line L12 rotates right at tt: aa is the root, with the left child a.lefta.left and the right child xx, and xx has the left child a.righta.right (the old one) and the right child bb. The edges that do not touch xx are a→a.lefta \to a.left and the edges inside the subtrees a.lefta.left, a.righta.right and bb; all are unchanged and good. The children of xx are a.righta.right, with a.right.pri≤a.pria.right.pri \le a.pri by (P2) for the old edge a→a.righta \to a.right, and bb, with b.pri<a.prib.pri < a.pri. So the new tree has (P2) except at xx, and so does the subtree ss rooted at xx, which has fewer nodes than tt. By induction, DELETE(s,k)(s, k) returns a treap s′s' with keys K(s)∖{k}K(s) \setminus \{k\} whose root is a node of ss other than xx, so its priority is at most a.pria.pri. The new tree, with root aa, left subtree a.lefta.left and right subtree s′s', is a treap with (P1), and its keys are K(t)∖{k}K(t) \setminus \{k\}. Its root aa is a node of tt other than xx. □\square

If kk is not in the tree, DELETE follows the search path to nil at line L7 and changes nothing.

Conclusion

Theorem. Starting from the empty tree, after any sequence of insertions and deletions the tree is a treap that holds exactly the keys inserted and not deleted since, and a search returns true exactly for these keys.

Proof. The empty tree is a treap. Lemma 1 and Lemma 2 (with xx the node of key kk) show that each operation keeps (P1) and (P2) and changes the key set as stated. A search is correct by (P1). ■\blacksquare

Back to Treap