Red Black Trees (2)
In this section, we will focus on the deletion. Deleting a node from a RBT takes \(O(\lg{N})\) time, and it is more complicated than inserting a node.
Delete a node (1)
A helper method
As part of the process of deleting a node, subtrees need to move around. The following subroutine transplant()
does the following work:
- replaces the subtree rooted at node
u
with the subtree rooted at nodev
- node
u
's parent becomes nodev
's parent u
's parent ends up havingv
as its child
First, let's design an algorithm to delete a node as if there were no color in nodes.
Deleting a node given a key
can be described as
- First, find a node
z
given akey
- Then, delete node
z
public void remove(int key) {
Node z = get(key);
if (z != null) {
delete(z);
}
}
Delete a node (2)
Recap the two cases of deleting a node z
in a BST:
- Case 1.
z
has at most one child. To deletez
, we use its child (it can benull
) to take the position ofz
. - Case 2.
z
has two children. Theny
is the successor ofz.right
. Ify
is notz.right
, execute step (a) and (b) sequentially; otherwise, execute only step (b).- (a)
y.right
(it can benull
) takes the position ofy
, and then updatey.right
toz.right
. - (b)
y
takes the position ofz
, and then updatey.left
toz.left
.
- (a)
In fact, case 2 can be transformed into case 1 by updating the z.key
to y.key
. In light of this, we can design a more readable algorithm:
By taking the leverage of the ternary conditional operator in Java, the code can be even shorter in practice for case 1:
Node<Key> x = (z.left != null) ? z.left : z.right;
transplant(z, x);
In Python, it can be written as:
x = z.left if z.left is not None else z.right
transplant(z, x)
Delete a node (3)
To delete a node z
in a RBT, we need to consider the color of it:
- If
z
is RED, then it will not violate any red-black tree property. - If
z
is BLACK, then it violates Property 5 (*change in black height).
We are going to say that Property 5 has not been violated and the node x
which is now occupying z
's original position has an extra black in it. In this way, the property of black height is not violated but Property 1 is violated, because x
now is either
- Double black, transformed from BLACK.
- Red and black, transformed from RED.
For example, deleting z
in the following result in a red and black node:
With this thinking, we can say that either Property 1, 2 or 4 can be violated. If x
is red and black or is root
, we can simply color it black.
What if
x
is null?Now let's consider a special case when
x
is null (i.e.,z
does not have any child). As we can see, the introduction of the sentinel (NIL
) will lead to simpler code, because we can regard it as a regular node whose color is always black. For example, we are able to up-swim to the parent from aNIL
, and \(v.p \gets u.p\) is always valid in thetransplant
.
Therefore, suppose z
has at most one child, we use its child x
to replace its position:
- Case a: if
z
is red, then just delete it. - Case b: if
z
is black with a red childx
, then colorx
to black. - Case c: if
z
is black, andx
is also black, then things get complicated, and we need to fix it up. In this case,x
is a double black node.
To understand case c, readers can try to maintain the BST by deleting 1:
In what follows, we will analyze four sub-cases for case c when x
is a left child, and another four cases when x
is a right child is symmetric.
Case 1: x
's sibling w
is red
Case 1 is transformed into case 2, 3, or 4 by exchanging the colors of nodes B and D and performing a left rotation.
Case 2: x
's sibling w
is black, and both of w
's children are black
To balance the black height, this cases removes one black from both x and w, leaving x with only one black and leaving w red. To compensate for x and w each losing one black, x.p
can take on an extra black. Line 16 does so by moving up x
to its parent.
Note that B is colored in brown, meaning it can be either black or red. If case 2 enters from case 1, then the new node x (i.e., B) is red-and-black. Then the while loop terminates.
Case 3: x
’s sibling w
is black, w
’s left child is red, and w
’s right child is black
This case switches the colors of w and its left child w.left, and then performs a right rotation on w. Then it falls through into case 4.
Case 4: x
's sibling w
is black, and w
's right child is red.
Some color changes and a left rotation on x.p allow the extra black on x to vanish. Note that D's color is set to the one of B. Line 31 sets x to root
, and the while loop will terminate.