Algorithm Search⌘K

Proofs: Binary search tree insertion

These are the human proofs of Binary search tree insertion, at full length.

BST insertion keeps the BST property and adds exactly the new key full

This proof shows: correctness, termination.

Let TT be a binary search tree with the strict binary search tree property, correct parent pointers, nn nodes and key set SS. Let kk be a key and vv a value. For a node uu write sub(u)\mathrm{sub}(u) for the nodes of its subtree.

Claim. TREE-INSERT(T,k,v)(T, k, v) stops after at most h+1h + 1 runs of the loop, where hh is the height of TT. Afterwards: (a) if k∈Sk \in S, the tree has the same nodes and links, and the node with key kk has value vv; (b) if k∉Sk \notin S, the tree has the nodes of TT plus one new leaf zz with key kk and value vv, it has the BST property, its parent pointers are correct, and T.n=n+1T.n = n + 1. No other value changes.

Step 1: the loop is the search. Lines L2 to L6 make the same moves as BST search for kk: at each node they stop on equality and else go to the left child if k<x.keyk < x.key and to the right child if k>x.keyk > x.key. Line L3 only copies xx to yy before the move. By the correctness of BST search, if k∈Sk \in S the loop reaches the node with key kk, and line L6 sets its value and returns; no link changes, which proves (a). The depth of xx grows by 1 in each run, so the loop runs at most h+1h + 1 times.

Step 2: the end of the path. Now let k∉Sk \notin S. Let u0,u1,…,umu_0, u_1, \ldots, u_m be the nodes that xx takes in the loop, with u0=T.rootu_0 = T.root (m=−1m = -1 when TT is empty). The loop ends when $x = $ NIL, so y=umy = u_m, and the move out of umu_m was to the left child if k<um.keyk < u_m.key and to the right child else, and that child is NIL. For each i<mi < m, ui+1u_{i+1} is the left child of uiu_i if k<ui.keyk < u_i.key and the right child if k>ui.keyk > u_i.key.

Step 3: the new leaf. If TT is empty, line L8 makes zz the root, with no parent, and a tree with one node has the BST property. Else lines L9 and L10 make zz the child of y=umy = u_m on the side given by the comparison of kk with um.keyu_m.key, which is the NIL child of Step 2, so no subtree is lost. Line L7 sets z.p=yz.p = y.

Step 4: the BST property. Take a node uu of the new tree and a node ww in its left subtree; we show w.key<u.keyw.key < u.key (the right side is the mirror image).

  • If u=zu = z, then uu has no subtrees, so there is no ww.
  • If w≠zw \ne z and u≠zu \ne z, then ww was in the left subtree of uu in TT, because the insert adds a leaf and changes no other link. So w.key<u.keyw.key < u.key by the property of TT.
  • If w=zw = z, then uu is an ancestor of zz, so u=uiu = u_i for some i≤mi \le m, and zz is in the left subtree of uiu_i exactly when the path went left at uiu_i, that is when k<ui.keyk < u_i.key. So w.key=k<u.keyw.key = k < u.key.

Step 5: links and count. The only new links are y→zy \to z (or the root field) and z.p=yz.p = y, and they agree. zz has no children. Line L11 adds 1 to T.nT.n. The keys of the new tree are S∪{k}S \cup \{k\}, and each old node keeps its key and value. This proves (b). ■\blacksquare

Corollary (sequence of inserts). By induction on the number of inserts, a tree built from the empty tree by TREE-INSERT has the BST property, and its in-order sequence is the sorted list of the distinct keys inserted, each with the value of its last insert.

Back to Binary search tree insertion