Proofs: Binary search tree
These are the human proofs of Binary search tree, at full length.
The operations of a binary search tree keep the invariant and return the right answers full
This proof shows: correctness.
We write for the set of keys of , and for the set of nodes in the subtree rooted at . The invariant is (B1) order, (B2) links and (B3) count, as on the page. We use one consequence of (B1) many times.
Lemma 1 (intervals). Assume (B1). For each node , let be the largest key of an ancestor of such that is in the right subtree of (or if there is none), and let be the smallest key of an ancestor such that is in the left subtree of (or ). Then each key in lies in the open interval , and each key of in this interval is in .
Proof. The first part follows from (B1) at each ancestor . For the second part, let be a node with , and let be the lowest common ancestor of and . If , then and are in different subtrees of , or . If is in the left subtree of , then , and by (B1) or by , so , which is false. The case where is in the right subtree is the mirror image. So , and .
Search. Claim: TREE-SEARCH returns the node with key if , and NIL else. We use the invariant of the loop of line L2: if , then the node with key is in (with ). Line L1 sets to the root, so it holds at the start. In a step, . If , then by (B1) no node of the right subtree and not itself has key , so the node with key , if it exists, is in the left subtree, and line L3 moves there. The case is the mirror image. Each step increases the depth of by 1, and the depth is at most , so the loop stops after at most steps. If it stops with NIL, then . If it stops with $x = $ NIL, then is empty, so by the invariant . The tree is not changed.
Minimum. Claim: TREE-MINIMUM returns the node of with the smallest key. Let be the path that lines L5 and L6 follow, where $x_m.left = $ NIL. For , each key of that is not in is or in the right subtree of , so it is larger than each key of by (B1). So the minimum of is the minimum of . The node has no left subtree, so by (B1) its key is the minimum of . By induction from down to , is the minimum of .
Successor. Claim: TREE-SUCCESSOR returns the node with the smallest key larger than , or NIL if is the maximum. Case 1: NIL. By Lemma 1 applied to , the keys of in are the keys of , because and . This set is not empty, so the successor is its minimum, which line L7 returns by the claim on minimum. Case 2: $x.right = $ NIL. Then by Lemma 1 no key of lies in , so the successor is the node with key if , and NIL else. The node with key is the lowest ancestor of such that is in the left subtree of : a lower such ancestor has a smaller key, because it is in the left subtree of each higher one. Lines L8 to L10 go up from while the current node is a right child, so they stop at the first ancestor entered from its left child, which is , or at NIL if there is none. By (B2) the parent pointers are right, so the walk follows the real path. The loop stops because the depth of drops by 1 in each step.
Insert. Claim: after TREE-INSERT, the tree holds the map with set to , and (B1) to (B3) hold. If , the loop of lines L12 to L15 is the search for , which reaches the node with key by the search claim, and line L15 changes only its value. Now let . The loop follows the search path for and stops when $x = $ NIL, with the last node of the path. Let be the empty child position of where the loop stopped (left if , right else). For each node on the path above this position, the path went left at exactly when . So the new node , placed at by lines L16 to L19, is in the left subtree of exactly when , and (B1) holds at each ancestor of . Nodes that are not ancestors of keep their subtrees, so (B1) holds there too, and has no subtrees. Line L16 sets , and the link from (or from when $y = $ NIL, which happens only for the empty tree) points to , so (B2) holds. The implementation adds 1 to in this case only, so (B3) holds.
Transplant. Claim: TRANSPLANT makes the parent of (or the root field) point to , and sets . This is lines L20 to L23 read directly; it changes no other link.
Delete. Claim: after TREE-DELETE, loses exactly , each other node keeps its key and value, and (B1) to (B3) hold. Let and . By Lemma 1, each key of lies in . The new subtree that takes the place of has the keys of without , so (B1) at the ancestors of stays true, and we only need (B1) inside the new subtree.
- Case A: $z.left = $ NIL (line L24). The new subtree is the right subtree of , which is a BST.
- Case B: $z.right = $ NIL (line L25). The new subtree is the left subtree of , which is a BST.
- Case C: two children (lines L26 to L28). Let and be the left and right subtrees of , and let $y = $ TREE-MINIMUM, the node of with the smallest key, so $y.left = $ NIL. Case C1: . Line L28 puts in the place of , with as its left subtree; its right subtree stays . Each key of is less than , and each key of is greater than because is the minimum of . Case C2: . Then is a left child inside . Line L27 replaces by its right subtree, which is (B1)-correct inside by the argument of case A applied to in the tree , so is a BST. Then gets as its right subtree, and line L28 puts in the place of with as its left subtree. Each key of is less than , and each key of is greater than . In both cases the new subtree is a BST with the keys of except .
For (B2): each link that the procedure changes is set in both directions. TRANSPLANT sets the child link and , and lines L27 and L28 set and after they set and . The node is no longer reachable from the root, because its only parent link (or the root field) now points to its replacement. The implementation subtracts 1 from , so (B3) holds.
Termination of the loops. Each loop of the main block moves one level down (lines L2, L5 and L12) or one level up (line L9), so it runs at most times.
Theorem. Starting from the empty tree, after any sequence of inserts and deletes, the tree satisfies (B1) to (B3) and stores exactly the map that the sequence defines, and each search, minimum and successor query returns the answer of the ordered set.
Proof. By induction on the number of operations. The empty tree satisfies (B1) to (B3) and stores the empty map. By the insert and delete claims, each update keeps the invariant and changes the map as the dictionary laws require. Queries do not change the tree, and by the search, minimum and successor claims they return the right node.