Red Black Trees
Red Black Trees
Properties 1. Every node is either red or black. 2. The root is black. 3. Every leaf (NIL) is black. 4. If a node is red, then both its children are black. 5. For each node (x), all paths from the node to descendant leaves contain the same number of black nodes i.e bh(x) = same through all paths
Structure with NIL(nodes) added seperately Structure with single NIL(T) node
Black – Height Property-5
Black – Height Property-5 Example: Height of a node: h(x) = # of edges in a longest path to a leaf. Black-height of a node bh(x) = # of black nodes on path from x to leaf, not counting x. How are they related? bh(x) ≤ h(x) ≤ 2 bh(x)
Red Black Tree? 19 35 12 50 75 -10 135 -5 100 -8 -6 80
Is it a Red Black Tree? Yes !..
Height of a red-black tree Theorem. A red-black tree with n keys has height h ≤ 2 log(n + 1). Proof. (The book uses induction from book)
Operations Rotate Rotations maintain the inorder ordering of keys: a ∈ α, b ∈ β, c ∈ γ ⇒ a ≤ A ≤ b ≤ B ≤ c. Rotations maintain the binary search tree property A rotation can be performed in O(1) Left-rotate(T,x) results into making its right child its parent Right-rotate(T,x) results into making its left child its parent
Rotation of pointer structure in RB Tree LEFT-ROTATE (T , x) y=x.right ** In 1 to 4 (x-to-beta) links updated x.right= y.left If y.left (Not Equal) NIL[T] then (y.left).p = x ** Update beta’s parent y.p = x.p ** In 5 to 7, parent of y updated and if x.p = NIL[T] then **checked if it is root T.root = y else if x = left [p[x]] then **In 8 to 10, left/ right of x’s parent updated left [p[x]] ← y else right [p[x]] ← y Left [ y] = x **In 11, 12 ( y-x ) links updated P[x] = y
Operations Insert- If inserting node 15 Preserving properties of both Binary search tree Red- Black Tree Properties that may be violated- 2- Root to be black OR 4- Red node always has black children
Insert a value into the RB Tree RB-TREE-INSERT(T , z) //z-the node to be inserted y=NIL[T] // y- temporary node x= T.root While x ≠ NIL[T] do y=x // y finally assigned to node where z can be inserted as child if z.key<x.key x=x.left else x=x.right z.p=y if y== NIL[T] // i.e z is first node being inserted T.root = z elseif z.key < y.key then // Manage y’s left/right pointer y.left=z else y.right = z z.left = NIL[T] z.right = NIL[T] z.color=RED RB-INSERT-FIXUP(T, z)
Insert a value into the RB Tree RB-INSERT-FIXUP(T, z) 1 while color[p[z]] = RED 2 do if p[z] = left[p[p[z]]] 3 then y ← right[p[p[z]]] // Uncle of z 4 if color[y] = RED 5 then color[p[z]] ← BLACK Case 1 6 color[y] ← BLACK Case 1 7 color[p[p[z]]] ← RED Case 1 8 z ← p[p[z]] Case 1 9 else if z = right[p[z]] //color[y] is black and LR case 10 then z ← p[z] Case 2 LEFT-ROTATE(T, z) Case 2 // Already color[y] is black and LL case 12 color[p[z]] ← BLACK Case 3 13 color[p[p[z]]] ← RED Case 3 14 RIGHT-ROTATE(T, p[p[z]]) Case 3 15 else (same as then clause with “right” and “left” exchanged) 16 color[root[T ]]← BLACK
Insert in an RB-Tree After Case-I RB TREE-FIXUP After RB TREE-INSERT After Case-II RB TREE-FIXUP After Case-III Left Rotate and re-color
Case 1 – uncle y is red p[p[z]] new z C C p[z] y A D A D z B B z is a right child here. Similar steps if z is a left child. p[p[z]] (z’s grandparent) must be black, since z and p[z] are both red and there are 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).
Case 2 – uncle y is black, z is a right child p[z] p[z] A y B y z z A B Converting LR case to LL case Left rotate around p[z], switch roles of p[z] and z now z is a left child of parent, and both z and p[z] are red. Takes us immediately to case 3.
Case 3 – y is black, z is a left child p[z] A C B y z A Make p[z] black and p[p[z]] red. Then right rotate on p[p[z]]. Ensures property 4 is maintained. No longer have 2 red’s in a row. p[z] is now black no more iterations.
Example Insert 17,25 in order in a tree
Example Inserting 25 further
Implications of the Rules If a Red node has any children, it must have two children and they must be Black. (Why?) If a Black node has only one child that child must be a Red leaf. (Why?) Due to the rules there are limits on how unbalanced a Red Black tree may become.
Height of RB-Tree for N Nodes If a Red Black Tree is complete, with all Black nodes except for Red leaves at the lowest level the height will be minimal, ~log N To get the maximum height for N elements there should be as many Red nodes as possible down one path and all other nodes are Black This means the max height would be < 2 * log N see example on next slide
Example of Inserting Sorted Numbers 1 2 3 4 5 6 7 8 9 10 Insert 1. A leaf so red. Realize it is root so recolor to black. 1 1
Insert 2 make 2 red. Parent is black so done. 1 2
Insert 3 1 Insert 3. Parent is red. Parent's sibling is black (null) 3 is outside relative to grandparent. Rotate parent and grandparent 2 3 2 1 3
Insert 4 2 When inserting 4, 3 Apply case-1 as uncle red 1 2->2 2 3
Insert 5 5's parent is red. Parent's sibling is black (null). 5 is outside relative to grandparent (3) so rotate parent and grandparent then recolor 2 1 3 4 5
Finish insert of 5 2 1 4 3 5
Insert 6 2 When adding 6, its uncle is red, so color both uncle and parent black and grandparent (4) red. 1 4 3 5 6
Finishing insert of 6 2 6's parent is black so done. 1 4 3 5 6
Insert 7 2 7's parent is red. Case-3 to be applied 1 4 3 5 6 7
Finish insert of 7 2 1 4 3 6 7 5
Insert 8 2 7's parent is red. Case-1 to be applied, node 6 then becomes red 1 4 3 6 7 5 8
Still Inserting 8 2 6's parent is red. Case-3 to be applied, node 6 then becomes red 1 4 3 6 7 5
Finish inserting 8 4 2 6 1 3 7 5 8
Operations Delete- If deleting node 15 Properties may be violated- Preserving properties of both Binary search tree Red- Black Tree Properties may be violated- If a node to be deleted is black
Deletion RB-TREE-DELETE (T, z) if left [z] = nil[T] .OR. right[z] = nil[T] then y ← z else y ← TREE-SUCCESSOR (z) if left [y] ≠ NIL then x ← left[y] else x ← right [y] if x ≠ NIL line removed then p[x] ← p[y] if p[y] = nil[T] then root [T] ← x else if y = left [p[y]] then left [p[y]] ← x else right [p[y]] ← x if y ≠ z then key [z] ← key [y] if y has other fields, copy them, too return y If color[y] = BLACK then RB-DELETE-FIXUP(T,x) return y
Deletion Fixup RB-DELETE-FIXUP(T, x) 1 while x ≠ root[T] and color[x] = BLACK 2 do if x = left[p[x]] then 3 w ← right[p[x]] 4 if color[w] = RED then 5 color[w] ← BLACK Case 1 6 color[p[x]] ← RED Case 1 7 LEFT-ROTATE(T, p[x]) Case 1 8 w ← right[p[x]] Case 1 9 if color[left[w]] = BLACK and color[right[w]] = BLACK then 10 color[w] ← RED Case 2 11 x ← p[x] Case 2 ** move one level above
Deletion Fixup RB-DELETE-FIXUP(T, x) … Ctd…. 11 x ← p[x] Case 2 ** move one level above 12 else if color[right[w]] = BLACK then 13 color[left[w]] ← BLACK Case 3 14 color[w]← RED Case 3 15 RIGHT-ROTATE(T,w) Case 3 16 w ← right[p[x]] Case 3 17 color[w] ← color[p[x]] Case 4 ** Right child not BLACK 18 color[p[x]] ← BLACK Case 4 19 color[right[w]] ← BLACK Case 4 20 LEFT-ROTATE(T, p[x]) Case 4 21 x ← root[T ] Case 4 22 else (same as then clause with “right” and “left” exchanged) 23 color[x] ← BLACK
Deletion Fixup Case-1 RB-DELETE-FIXUP(T, x) 1 while x ≠ root[T] and color[x] = BLACK 2 do if x = left[p[x]] then 3 w ← right[p[x]] 4 if color[w] = RED then 5 color[w] ← BLACK Case 1 6 color[p[x]] ← RED Case 1 7 LEFT-ROTATE(T, p[x]) Case 1 8 w ← right[p[x]] Case 1 9 if color[left[w]] = BLACK and color[right[w]] = BLACK then
Deletion Fixup Case-2 RB-DELETE-FIXUP(T, x) 1 while x ≠ root[T] and color[x] = BLACK 2 do if x = left[p[x]] then 3 w ← right[p[x]] 4 if color[w] = RED then 5 …….. 9 if color[left[w]] = BLACK and color[right[w]] = BLACK then 10 color[w] ← RED Case 2 x ← p[x] Case 2 ** move one level above 12 else if color[right[w]] = BLACK then
Deletion Fixup Case-3 RB-DELETE-FIXUP(T, x) … Ctd…. 11 x ← p[x] Case 2 ** move one level above 12 else if color[right[w]] = BLACK then // children of w,(Red,Black ) 13 color[left[w]] ← BLACK Case 3 14 color[w]← RED Case 3 15 RIGHT-ROTATE(T,w) Case 3 16 w ← right[p[x]] Case 3 color[w] ← color[p[x]] Case 4 ** Right child not BLACK
Deletion Fixup Case-4 RB-DELETE-FIXUP(T, x) … Ctd…. else if color[right[w]] = BLACK then ……. 16 w ← right[p[x]] Case 3 17 color[w] ← color[p[x]] Case 4 // children of w,(* ,Red ) 18 color[p[x]] ← BLACK Case 4 19 color[right[w]] ← BLACK Case 4 20 LEFT-ROTATE(T, p[x]) Case 4 21 x ← root[T ] Case 4 22 else (same as then clause with “right” and “left” exchanged) 23 color[x] ← BLACK
Deletion Delete the nodes 3, 18 and 22 one at a time from given tree
Deletion On deleting 3 RB Delete run RB Delete Fixup Case-1 RB Delete
Deletion On deleting 18 RB Delete run RB Delete Fixup Called While Condition has failed AS Color(x) is RED SO In Line no. 23 Change color(x) to BLACK
Deletion On deleting 22 RB Delete run