Transcript Lecture 24
Algorithms
CSCI 235, Fall 2015
Lecture 24
Red Black Trees
1
Properties of Red-black trees
1.
2.
3.
4.
5.
Every node is either red or black
The root is black
Every leaf (nil(T)) is black
If a node is red, both children are black
For each node, all paths from that node to the descendent leaves
contain the same number of black nodes.
26
17
14
NIL
NIL
Usually omitted
when drawing
trees
41
21
NIL
30
NIL
NIL
NIL
NIL
2
Red-Black Insertion
Insertion in a Red-Black Tree starts the same way as insertion into
a regular binary-search-tree.
Insert node z at the bottom of the tree by following the branches
from root to leaf in the correct order.
Then:
1) Color node z red.
2) Call RB-Insert-Fixup(T, z) to regain Red-Black Tree
properties.
3
RB-Insert(T, z) pseudocode
RB-Insert(T, z)
...
{Insert z into T, just like Binary-Search-Tree}
...
left[z] <- nil[T]
right[z] <- nil[T]
color[z] <- RED
RB-Insert-Fixup(T, z)
4
Fixing up the tree
What might need fixing?
Property
Description
1
Every node in the tree is red or black
2
The root is black
3
Every leaf (nil[T]) is black
4
If a node is red, both children are black
5
All paths from any given node to the
descendant leaves contain the same number
of black nodes.
True?
yes
?
yes
?
yes
Properties, 1, 3 and 5 still hold.
Therefore, we only need to check properties 2 and 4 and fix them if
5
they are violated.
Things we know
The following are true at the start of RB-Insert-Fixup:
a) Node z is red.
b) if p[z] is the root, then p[z] is black. Therefore, if p[z] is red,
then p[p[z]] exists.
c) If property 4) is violated, then it is because p[z] is red.
d) If property 2) is violated, it is because z is the root of the tree.
As we fix up the tree, we keep these facts the same after each iteration
of the fixup (i.e. they are loop invariant).
6
Cases to Consider
If property 2 is violated, then z is the root. Color z black and we
are done.
Cases to consider for Property 4:
Case 1: z's parent's sibling (i.e. z's uncle) is also red.
Case 2: z's uncle is black and z is a right child.
Case 3: z's uncle is black and z is a left child.
7
Case 1
Case 1: z's uncle is also red.
C z
C
uncle
D y
A
a
B z
b
g
A
a
D
B
b
g
a) Color both p[z] and uncle of z black.
b) Color p[p[z]] red (to maintain equal numbers of black nodes on
all paths.
c) Move z pointer up two levels (to p[p[z]]).
8
d) Repeat check for violation of properties 2 or 4.
Pseudocode for case 1
while color[p[z]] = RED do
{violation of property 4}
if p[z] = left[p[p[z]]] then
y <- right[p[p[z]]]
{y is uncle}
if color[y] = RED then
{case 1 applies}
color[p[z]] <- BLACK
color[y] <- BLACK
color[p[p[z]]] <- RED
z <- p[p[z]]
...{consider cases 2 and 3}
else
{else clause is the same except left and right exchanged}
9
Case 2
Case 2: z's uncle is black and z is a right child.
Use left rotation to convert to case 3.
Case 3: z's uncle is black and z is a left child.
C
uncle
D y
A
a
C
B z
B
g
A z
Case 2
b
g
a
if z = right[p[z]] then
z <- p[z]
Left-Rotate(T, z)
{Proceed with case 3}
D
uncle
y
Case 3
b
10
Case 3
Case 3: z's uncle is black and z is a left child.
B
C
uncle
D y
B
A z
a
g
zA
a
Case 3
C
b
g
D
b
1) Color p[z] black.
2) Color p[p[z]] red.
3) Perform right rotation.
After fixing case 3, we are done. There are no more violations (Why?)
11
Pseudocode for case 3
color[p[z]] <- BLACK
color[p[p[z]]] <- RED
Right-Rotate(T, p[p[z]])
{End of While loop}
{After the end of the while loop, set the root color to black:}
color[root[T]] <- BLACK {fix any violations of property 2}
Running time of RB-Insert-Fixup = ?
12