Proofs: Left-leaning red-black tree
These are the human proofs of Left-leaning red-black tree, at full length.
Insertion and deletion keep the left-leaning red-black rules full
This proof shows: correctness.
The rules are (L1) search order, (L2) no red right child, (L3) no red node with a red left child, (L4) the same number of black nodes on every path from the root to nil, and (L5) a black root. For a node , write for the number of black nodes on a path from down to nil, counting itself, with ; it is well defined when (L4) holds in the subtree of . Call a subtree valid when (L1) to (L4) hold in it; its root may be red. In a valid subtree, a red node has two black children: the left one by (L3), the right one by (L2).
Lemma A (the steps). A rotation of a red link, where the child moves up, takes the color of the old top, and the old top becomes red, keeps (L1), keeps (L4) in the subtree, and keeps of the top. A color flip at a node whose two children both have the color opposite to its own keeps (L1), (L4) and of the top.
Proof. A rotation keeps the in-order sequence of the keys. For ROTATE-LEFT with red, let be the color of and , , the subtrees , , . Before, a path from the top to , or meets the node of color and, for and , the red . After, it meets the node of color and, for and , the red . Red nodes add nothing, so each path has the same count. ROTATE-RIGHT is the mirror image. A flip at a black node with two red children makes the node red and the children black: a path from the top meets one black node before (the top) and one after (a child). The other flip is the reverse. Neither step changes keys.
Insertion
Lemma 1 (PUT). Let be valid or nil, and . Then has the keys and , (L1), (L2) and (L4) hold in its subtree, and (L3) holds at every node except possibly at itself. If is black or nil, (L3) holds at too, so is valid. If is red, then is red.
Proof. By induction on the size. If is nil, line L1 returns a red node with two nil children, which is valid, with . Else let be the child of on the side of and the result of the recursive call at line L2 or L3. Every node below satisfies the rules, and by Lemma A the steps of FIX-UP keep (L1), (L4) and . We follow FIX-UP in each case.
black, . Then is black, by (L2). If is black or nil, is valid by induction, so if is red its left child is black. No test of FIX-UP is true, and is valid. If is red, is red and only (L3) at may fail. If is red, line L7 rotates right at : the black top has the red left child and the red right child , whose new left child, the old , is black. Line L8 flips: the top is red with two black children, whose own children are black or valid. In both cases the result is valid.
black, . Then is black or nil and is valid. If is black, nothing changes. If is red and is black, line L6 rotates left: the top is black, its left child is red with two black children (the old , and the old , black since was red), and its right child is the black old . Lines L7 and L8 do nothing. If is red and is red, line L8 flips, and is red with two black children.
red. Its children are black. If , is valid, so line L7 does not apply (if is red, its left child is black), and stays red, with a possibly red left child. If and is red, line L6 rotates left: the top takes the red color of , and becomes its red left child, with two black children. Lines L7 and L8 do nothing. The top is red, and only (L3) at the top may fail.
INSERT. The root is black or nil, so by Lemma 1 PUT returns a valid tree with the new key. Line L10 paints the root black; this adds one to every path, so (L4) holds, and (L5) holds. An insertion of a key that is already there stops at line L4 with nothing changed (the implementation searches first).
Deletion
A call REMOVE has the precondition that , that (L1), (L3), (L4) hold in the subtree of and (L2) holds at every node except possibly at , and that one of these holds:
- (P1) is red, with two black children;
- (P2) is black, is red and is black;
- (P3) is black, is black, is red, and .
In the 2-3 view, (P1) and (P2) say that is not a 2-node, so a key can leave it. The postcondition is that the result is valid, with keys and , and that is black if was black when the call began. DELETE-MIN has the same precondition with (P1) or (P2), with the least key, and the same postcondition.
Lemma 2 (FIX-UP in deletion). If both children of are valid with the same , and if is red only when both children are black, then FIX-UP returns a valid subtree with the same keys and . If is black and is black, the result is itself, black.
Proof. If is red, its children are black and no test is true. If is black: with two black children nothing changes; with a red left child and a black right child, line L7 does not apply, since the left child is valid and red, so its left child is black; with a black left child and a red right child, line L6 rotates left and gives a black top with a red left child whose two children are black, as in Lemma 1; with two red children, line L8 flips and gives a red top with two black children.
Lemma 3 (MOVE-RED-LEFT). Let be red with valid black children and , and let be black. After MOVE-RED-LEFT, the subtree has the same keys and , (L1) and (L4) hold, and either (a) the top is , black, with two red children, each with two black children, or (b) the top is red, its right child is black and valid, and its left child is the old , black, with the red left child (whose children are black) and a black right child.
Proof. Line L16 flips at , a red node with two black children: is black, and and are red. The children of are black ( by assumption, by (L2)), and is black by (L2). If is black, the result is (a). Else let , red, with two black children. Line L17 rotates right at : takes the red color of and becomes its red right child, whose left child is the old , black. Then it rotates left at : moves up with the black color of , becomes its red left child, and the right child of is the old , black. Then it flips at , a black node with two red children: is red, and and are black. Now has the red left child and a black right child, and has two black children. Every step is one of Lemma A.
Lemma 4 (MOVE-RED-RIGHT). Let be red with valid black children and , and let be black. After MOVE-RED-RIGHT, the subtree has the same keys and , (L1) and (L4) hold, and either (a) the top is , black, with two red children, each with two black children, or (b) the top is red with two black children; is valid, and is the old , black, with a black left child and the red right child , whose children are black; and .
Proof. Line L18 flips at : is black, and and are red. The children of are black ( by assumption, by (L2)), and is black by (L2). If is black, the result is (a). Else is red, with black children. Line L19 rotates right at : moves up with the black color of , becomes its red right child, and the left child of is the old , black. Then it flips at , a black node with two red children: is red, is black, and is black. The node keeps the red right child . Since was the left child of , .
Lemma 5 (REMOVE and DELETE-MIN). Under the precondition, REMOVE and DELETE-MIN meet the postcondition.
Proof. By induction on the size. In every case below, the recursive call meets the precondition, so by induction it returns a valid subtree with the same as the child it replaces; then Lemma 2 applies to the last line, and we check its two conditions and the color of the result.
Case (lines L20 to L22). Since (P3) needs , this case has (P1) or (P2). The key is in , which is not nil.
- (P2): is red with black children, so line L21 does nothing and the call on has (P1). Line L22 replaces ; the right child of is black and unchanged. By Lemma 2, the result is , black.
- (P1) and red: line L21 does nothing. The call on the black has (P2) and returns a black node. At FIX-UP, is red with two black children, so Lemma 2 applies.
- (P1) and black: is not nil, since . Line L21 calls MOVE-RED-LEFT. In Lemma 3 (a), the call on the red left child has (P1), and at FIX-UP the top is black. In Lemma 3 (b), is less than the key of the old , which is the left child of the new top, so the recursion goes there, with (P2), and returns a black node; at FIX-UP the top is red with two black children.
Case (lines L23 to L27).
- (P2): line L23 rotates right at . The new top is the old , black, with the black left child (by (L3)) and the red right child , whose children are black. Now , line L24 does not apply ( nil), line L25 does nothing ( is red), and line L27 calls REMOVE on the red , which has (P1). At FIX-UP, is black with a black left child, so Lemma 2 gives a black result.
- (P3): line L23 does nothing, line L24 does not apply ( nil), and line L25 does nothing ( is red). The red right child has two black children, by (L3) and (L2) below . If , line L26 calls DELETE-MIN on it, and else line L27 calls REMOVE on it; both calls have (P1). At FIX-UP, is black with a black left child, and the result is black.
- (P1): line L23 does nothing. If and is nil, then and is black, so is nil: is a red leaf, and line L24 returns nil, with . Else is not nil, and neither is , by (L4). If is red, line L25 does nothing, and the call at line L26 or L27 on the black has (P2) and returns a black node; at FIX-UP, is red with two black children. If is black, line L25 calls MOVE-RED-RIGHT. In Lemma 4 (a), the call on the red right child has (P1), and the top is black at FIX-UP. In Lemma 4 (b), the new top has , so line L26 does not apply, and line L27 calls REMOVE on the old , which is black, with a black left child and a red right child, and : (P3). It returns a black node, so at the FIX-UP of , is red with two black children.
When line L26 runs, becomes the least key of . Every key of is less than , and every other key of is greater than , so after DELETE-MIN removes from , (L1) holds and the key is gone.
DELETE-MIN. If is nil, then (P2) is impossible, so is red, and as above is a red leaf and the result is nil. Else it runs the case above, with DELETE-MIN in place of REMOVE.
In every case the keys are , and is kept, by Lemma A, by induction and by Lemma 2. A result that comes from a call with black is black, as shown in each case.
DELETE. Line L11 makes sure that is in the tree. Before line L12 the tree is valid with a black root. If both children of the root are black, line L12 paints the root red, which subtracts one from every path and so keeps (L4); now (P1) holds. Else the root has a red child, which is the left one by (L2), and (P2) holds. By Lemma 5, REMOVE returns a valid tree without . Line L14 paints the root black, which keeps (L4) and gives (L5).
Conclusion
Theorem. Starting from the empty tree, after any sequence of insertions and deletions the tree satisfies (L1) to (L5) and holds exactly the keys inserted and not deleted since. A search returns true exactly for these keys.
Proof. The empty tree satisfies the rules. INSERT and DELETE keep them and change the key set as stated, by Lemma 1 and Lemma 5. A search is correct by (L1).