tfttypes of trees binary search treesbinary search trees · 2010. 5. 12. · - introducing avl...
TRANSCRIPT
Introduction to Algorithms
Chapter 12 & 13: Binary, AVL and Red-Black Trees
Revisiting TreesRevisiting Trees
- Revisiting BST
- Introducing AVL treesIntroducing AVL trees
I t d i R d Bl k T- Introducing Red-Black Trees
T f TTypes of Treestrees
static dynamicstatic y
game trees search trees i itgame trees search trees priority queues and heaps
graphs
2 3 ibinary searchtrees
AVL trees 2-3 trees tries Huffman coding tree
Red black
tree
Binary Search TreesBinary Search Trees
Binary Search Trees (BSTs) are an importantBinary Search Trees (BSTs) are an important data structure for dynamic sets
In addition to satellite data, elements have:k id tif i fi ld i d i t t l d ikey: an identifying field inducing a total orderingleft: pointer to a left child (may be NULL)right: pointer to a right child (may be NULL)p: pointer to a parent node (NULL for root)
Binary Search TreesBinary Search Trees
BST property:BST property: key[left(x)] ≤ key[x] ≤ key[right(x)]
Example:
F
B H
KDA
Inorder Tree WalkInorder Tree Walk
What does the following code do?What does the following code do?TreeWalk(x)
TreeWalk(left[x]);print(x);TreeWalk(right[x]);
A: prints elements in sorted (increasing) orderA: prints elements in sorted (increasing) orderThis is called an inorder tree walk
P d t lk i t t th l ft th i htPreorder tree walk: print root, then left, then rightPostorder tree walk: print left, then right, then root
Operations on BSTs: SearchOperations on BSTs: Search
Given a key and a pointer to a node returnsGiven a key and a pointer to a node, returns an element with that key or NULL:
TreeSearch(x, k)if (x = NULL or k = key[x])
return x;if (k < key[x])
return TreeSearch(left[x], k);else
return TreeSearch(right[x], k);
Operations on BSTs: SearchOperations on BSTs: Search
Here’s another function that does the same:Here s another function that does the same:
T S h( k)TreeSearch(x, k)while (x != NULL and k != key[x])
if (k k [ ])if (k < key[x])x = left[x];
elsex = right[x];
return x;
Operations of BSTs: InsertOperations of BSTs: Insert
Adds an element x to the tree so that theAdds an element x to the tree so that the binary search tree property continues to hold
The basic algorithmLik th h d bLike the search procedure aboveInsert x in place of NULLUse a “trailing pointer” to keep track of where you came from (like inserting into singly linked list)
BST Insert: ExampleBST Insert: Example
Example: Insert CExample: Insert C
FF
B HB H
KDA
C
BST Search/Insert: Running TimeBST Search/Insert: Running Time
What is the running time of TreeSearch() orWhat is the running time of TreeSearch() or TreeInsert()?A: O(h), where h = height of treeWhat is the height of a binary search tree?g yA: worst case: h = O(n) when tree is just a linear string of left or right childrenlinear string of left or right children
We’ll keep all analysis in terms of h for nowLater we’ll see how to maintain h = O(lg n)
Sorting With Binary Search TreesSorting With Binary Search Trees
Informal code for sorting array A of length n:Informal code for sorting array A of length n:BSTSort(A)
for i=1 to nTreeInsert(A[i]);
InorderTreeWalk(root);This is Ω(n lg n)This is Ω(n lg n)What will be the running time in the
W t ?Worst case? Average case?
Sorting With BSTsSorting With BSTs
Average case analysisAverage case analysisIt’s a form of quicksort!
for i=1 to nTreeInsert(A[i]);
InorderTreeWalk(root);
3 1 8 2 6 7 5 3
1 2 8 6 7 5 1 8
2 6 7 5 2 6
5 7
2 6 7 5 2 6
5 75 7 5 7
Sorting with BSTsSorting with BSTs
Same partitions are done as with quicksortSame partitions are done as with quicksort, but in a different order
In previous exampleEverything was compared to 3 onceTh h i 3 d 1Then those items < 3 were compared to 1 onceEtc.
S i i k t diff t d !Same comparisons as quicksort, different order!Example: consider inserting 5
We need 3 comparisons this is log(n) 3 tree heightWe need 3 comparisons, this is: log(n) = 3 = tree height
Sorting with BSTsSorting with BSTs
Since run time is proportional to the numberSince run time is proportional to the number of comparisons, same time as quicksort: O(n l )lg n)Which do you think is better, quicksort or BSTSort? Why?
Sorting with BSTsSorting with BSTs
Since run time is proportional to the numberSince run time is proportional to the number of comparisons, same time as quicksort: O(n l )lg n)Which do you think is better, quicksort or BSTSort? Why?A: quicksortA: quicksort
Better constantsSorts in placeSorts in placeDoesn’t need to build data structure
More BST OperationsMore BST Operations
BSTs are good for more than sorting ForBSTs are good for more than sorting. For example, can implement a priority queue
What operations must a priority queue have?InsertMinimumExtract-Min
For deletion, we will need a Successor() operation
BST Operations: DeleteBST Operations: Delete
Deletion is a bit trickyDeletion is a bit tricky3 cases: F
x has no children: Remove x
B H
x has one child: Splice out x
KDA
C Example: delete Kx has two children:
Swap x with successor
C or H or B
Perform case 1 or 2 to delete it
BST Operations: DeleteBST Operations: Delete
19
AVL TreesAVL Trees
Balanced binary search tree offer a O(log n)Balanced binary search tree offer a O(log n) insert and delete.
But balancing itself costs O(n) in the average case.
Is there any way to have a O(log n) insert too?
Yes, by almost but not fully balancing the tree : AVL (Adelson Velskii and Landis) balancingAVL (Adelson Velskii and Landis) balancing
AVL PropertyAVL Property
If N is a node in a binary tree node N hasIf N is a node in a binary tree, node N has AVL property if the heights of the left sub-tree
d i ht b t l if th diff band right sub-tree are equal or if they differ by 1.
In other words: AVL treesIn other words: AVL treesAVL Trees: Balanced search treeAVL Trees: Balanced search tree
Balance ensures that the search tree height will always be log nalways be log n AVL for Adelson-Velskii and LandisDefinition: If T is a nonempty binary tree with T andDefinition: If T is a nonempty binary tree with TL and TR as its left and right subtrees, then T is an AVL tree iffiff
TL and TR are AVL trees| hL - hR | ≤ 1| L R |
AVL Tree: ExampleAVL Tree: Example
k
ig ig
c he i
a c
AVL Tree: ExampleAVL Tree: Example
AVL Trees: Balanced Search treeAVL Trees: Balanced Search tree
Insertion: O (log n)Insertion: O (log n)
Deletion: O (log n)Deletion: O (log n)
Normally represented by a linked listy p y
Balance Factor (bf): The bf(x) of node x is defined to be as:be as:
Height of left subtree of x – height of right subtree of x e g t o e t subt ee o e g t o g t subt ee o
Red-Black TreesRed-Black Trees
The red black properties:The red-black properties:1. Every node is either red or black2. Every leaf (NULL pointer) is black
Note: this means every “real” node has 2 children3. If a node is red, both children are black
Note: can’t have 2 consecutive reds on a path4. Every path from node to descendent leaf
contains the same number of black nodes5. The root is always black
In other words: Red-Black TreeIn other words: Red Black Tree● A red-black tree can also be defined as a binary search
tree that satisfies the follo ing properties:tree that satisfies the following properties:■ Root Property: the root is black■ External Property: every leaf is black■ External Property: every leaf is black■ Internal Property: the children of a red node are black■ Depth Property: all the leaves have the same black depth■ Depth Property: all the leaves have the same black depth
9
154
62 12 2162 12
7
21
RB Trees: Worst-Case TimeRB Trees: Worst-Case Time
The red black tree has O(lg n) heightThe red-black tree has O(lg n) height
Corollary: These operations take O(lg n) time:Corollary: These operations take O(lg n) time: Minimum(), Maximum()S () P d ()Successor(), Predecessor()Search()
Insert() and Delete():Will also take O(lg n) timeBut will need special care since they modify tree
Red-Black Trees: An ExampleRed-Black Trees: An Example
Color this tree:Color this tree: 7
5 95 97
5 9
12125 9
Red-black properties:1. Every node is either red or black2. Every leaf (NULL pointer) is black3. If a node is red, both children are black4. Every path from node to descendent leaf
contains the same number of black nodes5. The root is always black5. The root is always black
Red-Black Trees: The Problem With Insertion
Insert 8Where does it go? 5 9
7Where does it go?
125 9
1. Every node is either red or black2. Every leaf (NULL pointer) is black3. If a node is red, both children are black3. If a node is red, both children are black4. Every path from node to descendent leaf
contains the same number of black nodes5 The root is always black5. The root is always black
Red-Black Trees: The Problem With Insertion
Insert 8Where does it go? 5 9
7g
What color should it be? 12
5 98
1. Every node is either red or black2. Every leaf (NULL pointer) is black3. If a node is red, both children are black3. If a node is red, both children are black4. Every path from node to descendent leaf
contains the same number of black nodes5 The root is always black5. The root is always black
Red-Black Trees: The Problem With Insertion
Insert 8Where does it go? 5 9
7g
What color should it be? 12
5 98
1. Every node is either red or black2. Every leaf (NULL pointer) is black3. If a node is red, both children are black3. If a node is red, both children are black4. Every path from node to descendent leaf
contains the same number of black nodes5 The root is always black5. The root is always black
Red-Black Trees:The Problem With Insertion
Insert 11Where does it go? 5 9
7g
125 9
8
1. Every node is either red or black2. Every leaf (NULL pointer) is black3. If a node is red, both children are black3. If a node is red, both children are black4. Every path from node to descendent leaf
contains the same number of black nodes5 The root is always black5. The root is always black
Red-Black Trees:The Problem With Insertion
Insert 11Where does it go? 5 9
7g
What color?12
5 98
111. Every node is either red or black2. Every leaf (NULL pointer) is black3. If a node is red, both children are black3. If a node is red, both children are black4. Every path from node to descendent leaf
contains the same number of black nodes5 The root is always black5. The root is always black
Red-Black Trees:The Problem With Insertion
Insert 11Where does it go? 5 9
7g
What color?Can’t be red! (#3) 12
5 98( )
111. Every node is either red or black2. Every leaf (NULL pointer) is black3. If a node is red, both children are black3. If a node is red, both children are black4. Every path from node to descendent leaf
contains the same number of black nodes5 The root is always black5. The root is always black
Red-Black Trees:The Problem With Insertion
Insert 11Where does it go? 5 9
7g
What color?Can’t be red! (#3) 12
5 98( )
Can’t be black! (#4) 111. Every node is either red or black2. Every leaf (NULL pointer) is black3. If a node is red, both children are black3. If a node is red, both children are black4. Every path from node to descendent leaf
contains the same number of black nodes5 The root is always black5. The root is always black
Red-Black Trees:The Problem With Insertion
Insert 11Where does it go? 5 9
7g
What color?Solution: 12
5 98
recolor the tree11
1. Every node is either red or black2. Every leaf (NULL pointer) is black3. If a node is red, both children are black3. If a node is red, both children are black4. Every path from node to descendent leaf
contains the same number of black nodes5 The root is always black5. The root is always black
Red-Black Trees:The Problem With Insertion
Insert 10Where does it go? 5 9
7g
125 9
811
1. Every node is either red or black2. Every leaf (NULL pointer) is black3. If a node is red, both children are black3. If a node is red, both children are black4. Every path from node to descendent leaf
contains the same number of black nodes5 The root is always black5. The root is always black
Red-Black Trees:The Problem With Insertion
Insert 10Where does it go? 5 9
7g
What color?12
5 98
111. Every node is either red or black2. Every leaf (NULL pointer) is black3. If a node is red, both children are black
103. If a node is red, both children are black4. Every path from node to descendent leaf
contains the same number of black nodes5 The root is always black5. The root is always black
Red-Black Trees:The Problem With Insertion
Insert 10Where does it go? 5 9
7g
What color?A: no color! Tree 12
5 98
is too imbalancedMust change tree structuret ll l i
11to allow recoloring
Goal: restructure tree in O(l ) ti
10O(lg n) time
Operations on RB TreesOperations on RB TreesAll operations can be performed in O(lg n)All operations can be performed in O(lg n)time.Th ti hi h d ’t dif thThe query operations, which don’t modify the tree, are performed in exactly the same way as they are in BSTs.Insertion and Deletion are not straightforward. g
RotationsRotations
yLeft Rotate(T x) y
x γ
Left-Rotate(T, x)
α
x
Ri ht R t t (T ) x
α β
γ
γ
α y
β
Right-Rotate(T, y)
α βγβ
RotationsRotationsRotations are the basic tree-restructuring operation for almost all balanced search treesfor almost all balanced search trees.Rotation takes a red-black-tree and a node, Changes pointers to change the local structure andChanges pointers to change the local structure, andWon’t violate the binary-search-tree property.Left rotation and right rotation are inversesLeft rotation and right rotation are inverses.
Left Rotate(T x) y
γ
Left-Rotate(T, x)
α
x
Ri ht R t t (T ) x
α β
γ
γ
α y
β
Right-Rotate(T, y)
α βγβ
Left Rotation – Pseudo-codeLeft Rotation – Pseudo-codeLeft-Rotate (T, x)1 y ← right[x] // Set y1. y ← right[x] // Set y.2. right[x] ← left[y] //Turn y’s left subtree into x’s right
subtree.3. if left[y] ≠ nil[T ]4. then p[left[y]] ← x5. p[y] ← p[x] // Link x’s parent to y.6. if p[x] = nil[T ]7. then root[T ] ← y8. else if x = left[p[x]]
th l ft[ [ ]]
y
x γ
Left-Rotate(T, x)
α
x
y Right-Rotate(T, y)9. then left[p[x]] ← y10. else right[p[x]] ← y11 left[y] ← x // Put x on y’s left
α βγβ
11. left[y] ← x // Put x on y s left.12. p[x] ← y
RotationRotationThe pseudo-code for Left-Rotate assumes that
right[x] ≠ nil[T ], androot’s parent is nil[T ].
Left Rotation on x, makes x the left child of y, and the left subtree of y into the right subtree of x.left subtree of y into the right subtree of x.
Pseudocode for Right-Rotate is symmetric: exchangePseudocode for Right Rotate is symmetric: exchange left and right everywhere.
Time: O(1) for both Left-Rotate and Right-Rotate, since a constant number of pointers are modified.
Rotation ExampleRotation Example
Rotate left about 9:Rotate left about 9:
7
125 9
8 12811
Rotation ExampleRotation Example
Rotate left about 9:Rotate left about 9:
75 12
99118
Red-Black Trees: InsertionRed-Black Trees: Insertion
Insertion: the basic ideaInsertion: the basic ideaInsert x into tree, color x redOnly r-b property 3 might be violated (if p[x] red)
If so, move violation up tree until a place is found where it can be fi edit can be fixed
Total time will be O(lg n)
Red-Black InsertRed-Black Insert
Insert node (z)Insert node (z)z.Color = red
This can cause two possible problems:Root must be black (initial insert violates this)Two red nodes cannot be adjacent (this is violated if parent of z is red)
ClCleanup
Red-Black CleanupRed-Black Cleanup
y = z’s “uncle”y = z s uncle
Three cases:y is redy is redy is black and z is a right childy is black and z is a left childy is black and z is a left child
Case 1 – z’s Uncle is redCase 1 – z s Uncle is red
y Color = blacky.Color = blackz.Parent.Color = blackz.Parent.Parent.Color = redz = z Parent Parentz = z.Parent.Parent
Repeat cleanup
Case 1 VisualizedCase 1 Visualized
11
2 14
71 15
5 8 y y.Color = blackz.Parent.Color = black
4z z.Parent.Parent.Color = redz = z.Parent.Parentrepeat cleanupNew repeat cleanupNode
Case 1 VisualizedCase 1 Visualized
11
2 14
71 15
5 8 y y.Color = blackz.Parent.Color = black
4z z.Parent.Parent.Color = redz = z.Parent.Parentrepeat cleanupNew repeat cleanupNode
Case 1 VisualizedCase 1 Visualized
11
2 14
71 15
5 8 y y.Color = blackz.Parent.Color = black
4z z.Parent.Parent.Color = redz = z.Parent.Parentrepeat cleanupNew repeat cleanupNode
Case 1 VisualizedCase 1 Visualized
11
2 14
71 15
5 8 y y.Color = blackz.Parent.Color = black
4z z.Parent.Parent.Color = redz = z.Parent.Parentrepeat cleanupNew repeat cleanupNode
Case 1 VisualizedCase 1 Visualized
11
2 14 y
71 15z
5 8 y.Color = blackz.Parent.Color = black
4 z.Parent.Parent.Color = redz = z.Parent.Parentrepeat cleanupNew repeat cleanupNode
Case 2 – z’s Uncle is black & z is aCase 2 – z s Uncle is black & z is a right childg
z = z.Parent
Left-Rotate(T, z)
Do Case 3Do Case 3
Note that Case 2 is a subset of Case 3
Case 2 VisualizedCase 2 Visualized
11
2 14 y
71 15z
5 8 z = z.ParentLeft-Rotate(T,z)
4Left Rotate(T,z)Do Case 3
Case 2 VisualizedCase 2 Visualized
11
2 14z y
71 15
5 8 z = z.ParentLeft-Rotate(T,z)
4Left Rotate(T,z)Do Case 3
Case 2 VisualizedCase 2 Visualized
11
147 y
2 158z
1 5 z = z.ParentLeft-Rotate(T,z)
4Left Rotate(T,z)Do Case 3
Case 3 – z’s Uncle is black & z is a leftCase 3 – z s Uncle is black & z is a left child
z.Parent.Color = black
z.Parent.Parent.Color = red
Right Rotate(T z Parent Parent)Right-Rotate(T, z.Parent.Parent)
Case 3 VisualizedCase 3 Visualized
11
147 y
2 158z
1 5
4z.Parent.Color = blackz.Parent.Parent.Color = redRight-Rotate(T, z.Parent.Parent)g ( , )
Case 3 VisualizedCase 3 Visualized
11
147 y
2 158z
1 5
P t C l bl k4
z.Parent.Color = blackz.Parent.Parent.Color = redRight-Rotate(T, z.Parent.Parent)g ( )
Case 3 VisualizedCase 3 Visualized
11
147 y
2 158z
1 5
4z.Parent.Color = blackz.Parent.Parent.Color = redRight-Rotate(T, z.Parent.Parent)g ( , )
Case 3 VisualizedCase 3 Visualized
7
112z
141 5 8 y
154
z.Parent.Color = blackz.Parent.Parent.Color = redRight-Rotate(T z Parent Parent)Right-Rotate(T, z.Parent.Parent)
Trees - Red Black TreesTrees - Red-Black Trees
Data structureAs we’ll see, nodes in red-black trees need to know their parents,
Same as a
so we need this data structure
t t t d bl k d { binary treewith these two
attributes
struct t_red_black_node {enum { red, black } color;void *item;
addedvoid item;struct t_red_black_node *left,
*right,*parent;
}
Trees - InsertionTrees - InsertionInsertion of a new node
Requires a re balance of the treeRequires a re-balance of the tree
rb_insert( Tree T, node x ) {/* Insert in the tree in the usual way *//* Insert in the tree in the usual way */tree_insert( T, x );/* Now restore the red-black property */x->color = red;x->color = red;while ( (x != T->root) && (x->parent->color == red) ) {
if ( x->parent == x->parent->parent->left ) {/* If x's parent is a left, y is x's right 'uncle' */
Insert node4
Mark it red p , y gy = x->parent->parent->right;if ( y->color == red ) {
/* case 1 - change the colors */x >parent >color black;
Label the current node
Mark it red
x->parent->color = black;y->color = black;x->parent->parent->color = red;/* Move x up the tree */
x
px = x->parent->parent;
Trees - InsertionTrees - Insertion
rb_insert( Tree T, node x ) {/ //* Insert in the tree in the usual way */tree_insert( T, x );/* Now restore the red-black property */x->color = red;x->color = red;while ( (x != T->root) && (x->parent->color == red) ) {
if ( x->parent == x->parent->parent->left ) {/* If x's parent is a left, y is x's right 'uncle' */While we haven’t reached the rootp , y gy = x->parent->parent->right;if ( y->color == red ) {
/* case 1 - change the colors */x >parent >color black
and x’s parent is red
x->parent->color = black;y->color = black;x->parent->parent->color = red;/* Move x up the tree */
x->parent
px = x->parent->parent;
Trees - InsertionTrees - Insertion
rb_insert( Tree T, node x ) {/ //* Insert in the tree in the usual way */tree_insert( T, x );/* Now restore the red-black property */x->color = red;x >color = red;while ( (x != T->root) && (x->parent->color == red) ) {
if ( x->parent == x->parent->parent->left ) {/* If x's parent is a left, y is x's right 'uncle' */If x is to the left of it’s granparentp , y gy = x->parent->parent->right;if ( y->color == red ) {
/* case 1 - change the colors */x >parent >color blackx->parent->parentx->parent->color = black;y->color = black;x->parent->parent->color = red;/* Move x up the tree */
x->parentp
x = x->parent->parent;
Trees - InsertionTrees - Insertion
/ //* Now restore the red-black property */x->color = red;while ( (x != T->root) && (x->parent->color == red) ) {
if ( x >parent == x >parent >parent >left ) {if ( x->parent == x->parent->parent->left ) {/* If x's parent is a left, y is x's right 'uncle' */y = x->parent->parent->right;if ( y->color == red ) {y is x’s right uncleif ( y >color red ) {
/* case 1 - change the colors */x->parent->color = black;y->color = black;x->parent->parentx->parent->parent->color = red;/* Move x up the tree */x = x->parent->parent;
x->parentright “uncle”
Trees - InsertionTrees - Insertion
while ( (x != T->root) && (x->parent->color == red) ) {if ( t t t l ft ) {if ( x->parent == x->parent->parent->left ) {
/* If x's parent is a left, y is x's right 'uncle' */y = x->parent->parent->right;if ( y >color == red ) {if ( y->color == red ) {
/* case 1 - change the colors */x->parent->color = black;y->color = black;y->color = black;x->parent->parent->color = red;/* Move x up the tree */x = x->parent->parent;x->parent->parent
If the uncle is red, changethe colors of y the grand-parentp p
x->parentx >parent >parent
right “uncle”
the colors of y, the grand-parent and the parent
right uncle
Trees - InsertionTrees - Insertion
while ( (x != T->root) && (x->parent->color == red) ) {if ( t t t l ft ) {if ( x->parent == x->parent->parent->left ) {
/* If x's parent is a left, y is x's right 'uncle' */y = x->parent->parent->right;if ( y >color == red ) {if ( y->color == red ) {
/* case 1 - change the colors */x->parent->color = black;y->color = black;y->color = black;x->parent->parent->color = red;/* Move x up the tree */x = x->parent->parent;p p
Trees - InsertionTrees - Insertion
while ( (x != T->root) && (x->parent->color == red) ) {if ( l f ) {if ( x->parent == x->parent->parent->left ) {/* If x's parent is a left, y is x's right 'uncle' */y = x->parent->parent->right;if ( > l d ) {if ( y->color == red ) {
/* case 1 - change the colors */x->parent->color = black;y->color = black;x’s parent is a left again,y ;x->parent->parent->color = red;/* Move x up the tree */x = x->parent->parent;
mark x’s unclebut the uncle is black this time
New xNew x
Trees - InsertionTrees - Insertion
while ( (x != T->root) && (x->parent->color == red) ) {if ( > t > t > t >l ft ) {if ( x->parent == x->parent->parent->left ) {
/* If x's parent is a left, y is x's right 'uncle' */y = x->parent->parent->right;if ( y->color == red ) {but the uncle is black this time( y ) {/* case 1 - change the colors */x->parent->color = black;y->color = black;x->parent->parent->color = red;/* M th t */
.. but the uncle is black this timeand x is to the right of it’s parent
/* Move x up the tree */x = x->parent->parent;else {
/* y is a black node */if ( x == x->parent->right ) {
/* and x is to the right */ /* case 2 - move x up and rotate */x = x->parent;left_rotate( T, x );
Trees - InsertionTrees - Insertion
while ( (x != T->root) && (x->parent->color == red) ) {if ( > t > t > t >l ft ) {if ( x->parent == x->parent->parent->left ) {
/* If x's parent is a left, y is x's right 'uncle' */y = x->parent->parent->right;if ( y->color == red ) {So move x up and( y ) {/* case 1 - change the colors */x->parent->color = black;y->color = black;x->parent->parent->color = red;/* M th t */
.. So move x up and rotate about x as root ...
/* Move x up the tree */x = x->parent->parent;else {
/* y is a black node */if ( x == x->parent->right ) {
/* and x is to the right */ /* case 2 - move x up and rotate */x = x->parent;left_rotate( T, x );
Trees - InsertionTrees - Insertion
while ( (x != T->root) && (x->parent->color == red) ) {if ( > t > t > t >l ft ) {if ( x->parent == x->parent->parent->left ) {
/* If x's parent is a left, y is x's right 'uncle' */y = x->parent->parent->right;if ( y->color == red ) {( y ) {/* case 1 - change the colors */x->parent->color = black;y->color = black;x->parent->parent->color = red;/* M th t *//* Move x up the tree */x = x->parent->parent;else {
/* y is a black node */if ( x == x->parent->right ) {
/* and x is to the right */ /* case 2 - move x up and rotate */x = x->parent;left_rotate( T, x );
Trees - InsertionTrees - Insertion
while ( (x != T->root) && (x->parent->color == red) ) {if ( > t > t > t >l ft ) {if ( x->parent == x->parent->parent->left ) {
/* If x's parent is a left, y is x's right 'uncle' */y = x->parent->parent->right;if ( y->color == red ) {( y ) {/* case 1 - change the colors */x->parent->color = black;y->color = black;x->parent->parent->color = red;/* M th t *//* Move x up the tree */x = x->parent->parent;else {
/* y is a black node */if ( x == x->parent->right ) {
/* and x is to the right */ /* case 2 - move x up and rotate */
.. but x’s parent is still red ...
x = x->parent;left_rotate( T, x );
Trees - InsertionTrees - Insertionwhile ( (x != T->root) && (x->parent->color == red) ) {if ( x >parent == x >parent >parent >left ) {if ( x->parent == x->parent->parent->left ) {/* If x's parent is a left, y is x's right 'uncle' */y = x->parent->parent->right;if ( y->color == red ) {if ( y->color == red ) {
/* case 1 - change the colors */x->parent->color = black;y->color = black;x->parent->parent->color = red;
.. The uncle is black ..
/* Move x up the tree */x = x->parent->parent;
else {/* y is a black node */
uncle
/ y /if ( x == x->parent->right ) {
/* and x is to the right */ /* case 2 - move x up and rotate */x = x->parent;
.. and x is to the left of its parentp
left_rotate( T, x );
Trees - InsertionTrees - Insertionwhile ( (x != T->root) && (x->parent->color == red) ) {if ( x->parent == x->parent->parent->left ) {( p p p ) {/* If x's parent is a left, y is x's right 'uncle' */y = x->parent->parent->right;if ( y->color == red ) {
/* case 1 - change the colors */x->parent->color = black;y >color = black;y->color = black;x->parent->parent->color = red;/* Move x up the tree */x = x->parent->parent;
else {/* y is a black node */
.. So we have the final case ..
if ( x == x->parent->right ) {/* and x is to the right */ /* case 2 - move x up and rotate */x = x->parent;left_rotate( T, x );
l { /* 3 */else { /* case 3 */x->parent->color = black;x->parent->parent->color = red;right rotate( T x->parent->parent );right_rotate( T, x->parent->parent );}
Trees - InsertionTrees - Insertionwhile ( (x != T->root) && (x->parent->color == red) ) {if ( x->parent == x->parent->parent->left ) {( p p p ) {/* If x's parent is a left, y is x's right 'uncle' */y = x->parent->parent->right;if ( y->color == red ) {
/* case 1 - change the colors */x->parent->color = black;y >color = black;y->color = black;x->parent->parent->color = red;/* Move x up the tree */x = x->parent->parent;
else {/* y is a black node */
.. Change colorsand rotate ..
if ( x == x->parent->right ) {/* and x is to the right */ /* case 2 - move x up and rotate */x = x->parent;left_rotate( T, x );
l { /* 3 */else { /* case 3 */x->parent->color = black;x->parent->parent->color = red;right rotate( T x->parent->parent );right_rotate( T, x->parent->parent );}
Trees - InsertionTrees - Insertionwhile ( (x != T->root) && (x->parent->color == red) ) {if ( x->parent == x->parent->parent->left ) {( p p p ) {/* If x's parent is a left, y is x's right 'uncle' */y = x->parent->parent->right;if ( y->color == red ) {
/* case 1 - change the colors */x->parent->color = black;y >color = black;y->color = black;x->parent->parent->color = red;/* Move x up the tree */x = x->parent->parent;
else {/* y is a black node */if ( x == x->parent->right ) {
/* and x is to the right */ /* case 2 - move x up and rotate */x = x->parent;left_rotate( T, x );
l { /* 3 */else { /* case 3 */x->parent->color = black;x->parent->parent->color = red;right rotate( T x->parent->parent );right_rotate( T, x->parent->parent );}
Trees - InsertionTrees - Insertionwhile ( (x != T->root) && (x->parent->color == red) ) {if ( x->parent == x->parent->parent->left ) {( p p p ) {/* If x's parent is a left, y is x's right 'uncle' */y = x->parent->parent->right;if ( y->color == red ) {
/* case 1 - change the colors */x->parent->color = black;y >color = black;
This is now a red-black tree ..S ’ fi i h d!y->color = black;
x->parent->parent->color = red;/* Move x up the tree */x = x->parent->parent;
else {/* y is a black node */
So we’re finished!
if ( x == x->parent->right ) {/* and x is to the right */ /* case 2 - move x up and rotate */x = x->parent;left_rotate( T, x );
l { /* 3 */else { /* case 3 */x->parent->color = black;x->parent->parent->color = red;right rotate( T x->parent->parent );right_rotate( T, x->parent->parent );}
Trees - InsertionTrees - Insertion
while ( (x != T->root) && (x->parent->color == red) ) {if ( t t t l ft ) {if ( x->parent == x->parent->parent->left ) {/* If x's parent is a left, y is x's right 'uncle' */y = x->parent->parent->right;if ( y->color == red ) {
/* case 1 - change the colors */> t > l bl k
There’s an equivalent set ofh th t i tx->parent->color = black;
y->color = black;x->parent->parent->color = red;/* Move x up the tree */x = x->parent->parent;
else {
cases when the parent is tothe right of the grandparent!
/* y is a black node */if ( x == x->parent->right ) {
/* and x is to the right */ /* case 2 - move x up and rotate */x = x->parent;left rotate( T x );left_rotate( T, x );
else { /* case 3 */x->parent->color = black;x->parent->parent->color = red;right_rotate( T, x->parent->parent );}}
}else ....
Red-black trees - AnalysisRed-black trees - Analysis
AdditionAdditionInsertion Comparisons O(log n)Fix-upFix up
At every stage,x moves up the tree at least one level O(log n)at least one level O(log n)
Overall O(log n)DeletionDeletion
Also O(log n)More complexMore complex... but gives O(log n) behavior
Another version of insertionStart by doing regular binary-search-tree insertion:
• RB-INSERT ends by coloring the new node z red.
• Then it calls RB-INSERT-FIXUPThen it calls RB INSERT FIXUP because we could have violated a red-black property.
Whi h t i ht b i l t d?• Which property might be violated?1. OK.2. If z is the root,
then there’s a violation Otherwise OKthen there’s a violation. Otherwise, OK.3. OK.4. If p[z] is red, there’s a violation:
both z and p[z] are redboth z and p[z] are red.5. OK.
• Remove the violation by calling RB-INSERT-FIXUP:
continued.. continuedLoop Invariant : At the start of each iteration of the while loop,
i da. z is red.b. There is at most one red-black violation:
• Property 2: z is a red root, or• Property 4: z and p[z] are both red.p y p[ ]
Initialization: We’ve already seen why the loop invariant holds initially.
Termination: The loop terminates because p[z] is black. Hence, property 4 is OK. Only property 2 might be violated and the last lineOnly property 2 might be violated, and the last line fixes it.
Maintenance: We drop out when z is the root (since then p[z] is theWe drop out when z is the root (since then p[z] is the sentinel nil[T ], which is black). When we start the loop body, the only violation is of property 4.There are 6 cases
- 3 of which are symmetric to the other 3.3 of which are symmetric to the other 3. The cases are not mutually exclusive. Consider cases in which p[z] is a left child.
Let y be z’s uncle (p[z]’s sibling).
C.. continued
Case 1: y is redp[p[z]] (z’s grandparent) must be black, since z and p[z] are both red and there are no other violations of property 4are no other violations of property 4.Make p[z] and y black ⇒ now z and p[z] are not both red. But property 5 might now be violated.Make p[p[z]] red ⇒ restores property 5.The next iteration has p[p[z]] as the new z (i.e., z moves up 2 levels).( p )
Case 2: y is black, z is a right childLeft rotate around p[z] ⇒ now z is a left child and both z and p[z] are redchild, and both z and p[z] are red.Takes us immediately to case 3.
Case 3: y is black, z is a left childyMake p[z] black and p[p[z]] red.Then right rotate on p[p[z]].No longer have 2 reds in a row.gp[z] is now black ⇒ no more iterations.
continued.. continued
Analysis
O(lg n) time to get through RB-INSERT up to the call of RB-( g ) g g pINSERT-FIXUP.
Within RB-INSERT-FIXUP:Each iteration takes O(1) time.Each iteration is either the last one or it moves z up 2 levels.O(lg n) levels ⇒ O(lg n) time.
Thus insertion into a red-black tree takes O(lg n) timeThus, insertion into a red-black tree takes O(lg n) time.
Red-Black Trees: DeletionRed-Black Trees: DeletionDeletion, like insertion, should preserve all the RB properties.The properties that may be violated depends p p y pon the color of the deleted node.
Red – OK Why?Red – OK. Why?Black?
StSteps:Do regular BST deletion.Fix any violations of RB properties that may result.
DeletionDeletionRB-Delete(T, z)
f f1. if left[z] = nil[T] or right[z] = nil[T]2. then y ← z
l TREE SUCCESSOR( )3. else y ← TREE-SUCCESSOR(z)4. if left[y] ≠ nil[T ]
then x ← left[y]5. then x ← left[y]6. else x ← right[y]7 p[x] ← p[y] // Do this even if x is nil[T]7. p[x] ← p[y] // Do this, even if x is nil[T]
DeletionDeletionRB-Delete (T, z) (Contd.)8 if p[y] = nil[T ]8. if p[y] = nil[T ]9. then root[T ] ← x10. else if y = left[p[y]]10. else if y left[p[y]]11. then left[p[y]] ← x12. else right[p[y]] ← xg [p[y]]13. if y ≠ z14. then key[z] ← key[y] The node passed to y y y15. copy y’s satellite data into z16. if color[y] = BLACK
pthe fixup routine is the lone child of th li d17. then RB-Delete-Fixup(T, x)
18. return y
the spliced up node, or the sentinelsentinel.
Tree SuccessorTree Successor
TREE SUCCESSOR(x)TREE-SUCCESSOR(x)1 if right[x] ≠ NIL2 then return TREE-MINIMUM (right[x])3 y ← p[x]3 y ← p[x]4 while y ≠ NIL and x = right[y]5 do x ← y6 y ← p[y]6 y p[y]7 return y
96
RB Properties ViolationRB Properties Violation
If y is black we could have violations of redIf y is black, we could have violations of red-black properties:
1 OProp. 1. OK.Prop. 2. If y is the root and x is red, then the root has become red.Prop. 3. OK.Prop. 4. Violation if p[y] and x are both red.Prop. 5. Any path containing y now has 1 fewer p y p g yblack node.
RB Properties ViolationRB Properties ViolationProp. 5. Any path containing y now has 1 fewer p y p g yblack node.
Correct by giving x an “extra black.”Add 1 to count of black nodes on paths containing x.Now property 5 is OK, but property 1 is not.x is either doubly black (if color[x] = BLACK) or red & black (if color[x] = RED).The attribute color[x] is still either RED or BLACK NoThe attribute color[x] is still either RED or BLACK. No new values for color attribute.
Remove the violations by calling RB-Delete-Remove the violations by calling RB DeleteFixup.
Deletion – FixupDeletion Fixup
RB-Delete-Fixup(T x)RB-Delete-Fixup(T, x)1. while x ≠ root[T ] and color[x] = BLACK2 do if x = left[p[x]]2. do if x = left[p[x]]3. then w ← right[p[x]]4 if color[w] = RED4. if color[w] = RED5. then color[w] ← BLACK // Case 16 color[p[x]] RED // Case 16. color[p[x]] ← RED // Case 17. LEFT-ROTATE(T, p[x]) // Case 1
right[p[ ]] // Case 18. w ← right[p[x]] // Case 1
RB-Delete-Fixup(T, x) (Contd.)/* x is still left[p[x]] */
9. if color[left[w]] = BLACK and color[right[w]] = BLACK10. then color[w] ← RED // Case 211 x ← p[x] // Case 211. x ← p[x] // Case 212. else if color[right[w]] = BLACK13. then color[left[w]] ← BLACK // Case 314. color[w] ← RED // Case 315. RIGHT-ROTATE(T,w) // Case 3
w ← right[p[x]] // Case 316. w ← right[p[x]] // Case 317. color[w] ← color[p[x]] // Case 418. color[p[x]] ← BLACK // Case 418. color[p[x]] ← BLACK // Case 419. color[right[w]] ← BLACK // Case 420. LEFT-ROTATE(T, p[x]) // Case 421. x ← root[T ] // Case 422. else (same as then clause with “right” and “left”
exchanged)g )23. color[x] ← BLACK
Deletion – FixupDeletion – Fixup Idea: Move the extra black up the tree until x pointsIdea: Move the extra black up the tree until x points to a red & black node ⇒ turn it into a black node,x points to the root ⇒ just remove the extra black, or po ts to t e oot ⇒ just e o e t e e t a b ac , oWe can do certain rotations and re-colorings and finish.Within the while loop:
x always points to a non-root doubly black node.w is x’s sibling.w cannot be nil[T ], since that would violate property 5 at p[x]p[x].
8 cases in all, 4 of which are symmetric to the other.
Case 1 – w is redw is red => it has black childrenswitch colors of w, p[w] and left-rotate p[w]Result: one of the other casesResult: one of the other cases
b
d
d
x wa d b e
c e x new wa c
In other words :Case 1 – w is redB D
p[x]
A D Bx w
D
E
C Eα β A
α β δ
ε ζCx new w
w must have black children.γ δ ε ζ
α β γ δ
Make w black and p[x] red (because w is red p[x] couldn’t have been red).Then left rotate on p[x]Then left rotate on p[x].New sibling of x was a child of w before rotation ⇒ must be black.G i di t l t 2 3 4Go immediately to case 2, 3, or 4.
Case 2 – w is black, both w’s children are black,
w is black with black childrenRepeat the whole procedure for p[x] as the new xnew x
b b
x wa
b
d a
b
d
new x
x wa
c
d
e
a
c
d
e
i
c e c e
for nodes that may be either red or black
Case 3 – w is black w’s left child is redCase 3 – w is black, w s left child is red, w’s right child is blackg
B Bc cB
A Dx w
B
A C
c
new wx
C Eα β Dα β
γ
Make w red and w’s left child black. ζ
γ δ ε ζδ
ε
E
a e ed a d s e t c d b acThen right rotate on w.New sibling w of x is black with a red right child ⇒ case 4.
ζε
New sibling w of x is black with a red right child ⇒ case 4.
Case 4 – w is black, w’s right child is red, g
B Dc
B
A D Bx w
D
E
C Eα β A
α β
ε ζCxc’
Make w be p[x]’s color (c).γ δ ε ζ
α β γ δ
Make p[x] black and w’s right child black.Then left rotate on p[x].Remove the extra black on x (⇒ x is now singly black) without violating any red-black properties.All d S tti t t th l t t i tAll done. Setting x to root causes the loop to terminate.
AnalysisAnalysisO(lg n) time to get through RB-Delete up toO(lg n) time to get through RB-Delete up to the call of RB-Delete-Fixup.Within RB Delete Fixup:Within RB-Delete-Fixup:
Case 2 is the only case in which more iterations occuroccur.
x moves up 1 level.Hence, O(lg n) iterations.Hence, O(lg n) iterations.
Each of cases 1, 3, and 4 has 1 rotation ⇒ ≤ 3 rotations in all.Hence, O(lg n) time.