Red Black Trees Dr Hicks Trinity University Some
Red Black Trees Dr. Hicks Trinity University
Some Balanced Tree Variations • Randomly-built BSTs – Reasonably balanced in expected case. – Only feasible if all inserts happen first, & can randomize their relative order. • AVL trees (1962) – BSTs. – Guarantees depths of all leaves differ by at most 1. – Balancing requires O(log n) rotations. • Red-Black trees (1972) – – BSTs. Guarantees depth of all leaves within a factor of 2. Balancing requires at most 2 rotations. Will discuss in detail. • AA-trees (1996) – Easier-to-code variant of Red-Black trees.
Some Balanced Tree Variations • 2 -3 trees (1970) – Search tree, where nodes have either 2 or 3 children and 1 or 2 keys, respectively – Guarantees depth of all leaves within a constant factor. • 2 -3 -4 trees – Generalization of 2 -3 trees. – Guarantees depth of all leaves equal. – Lower constant costs than 2 -3 trees, because only makes one pass on tree, instead of two, on each operation. – Can be viewed as an implementation of red-black trees. • B-trees (1972) – Generalization of 2 -3 & 2 -3 -4 trees to unbounded size nodes. – Bushy, shallow trees minimize the number of node accesses so as to minimize I/O operations when the tree is stored on disk. – Most suitable for huge data sets, as in databases.
Some Balanced Tree Variations • Splay trees (1983) – Self-adjusting, i. e. , changes tree even on non-insert/delete operations, so as to improve later accesses. – Logarithmic bounds only when amortized. – Will discuss in detail. • Skip lists (1990) – Singly-linked sorted lists, with extra pointers to later in list. – Conceptually simple. – High space overhead for lots of pointers, and logarithmic bounds only expected. • Treaps (1996) – BSTs & heaps. – Conceptually, fairly simple. – Low constant costs, but logarithmic bounds only expected.
AVL Some Applets http: //www. site. uottawa. ca/=stan/csi 2514/applets/avl/BT. html Red-Black http: //www. ececs. uc. edu/=franco/C 321/html/Red. Black/redblack. html 2 -3 -4 http: //www. cis. temple. edu/=pwang/223 DS/Workshop. Applets/Chap 10/Tree 234. html Splay http: //www. ibr. cs. tu-bs. de/lehre/ss 98/audii/applets/BST/Splay. Tree. Example. html Skip list http: //iamwww. unibe. ch/=wenger/DA/Skip. List/ BST, AVL, Red-Black, AA, Splay, Tries, Patricia Tries http: //www. cis. ksu. edu/=howell/viewer. html
Definition • A red-black tree is a binary search tree with one extra bit of information in each node: a color, which can be red or black • By constraining node color we can ensure that no path from root to leaf is more than twice as long as any other so that the tree remains approximately balanced • Each node contains color, value, left, right and parent [maybe deleted] Parent = NILL if a child or it has no parent.
Red Black Rules 1 - 3 Red Black Trees are binary trees with the following properties. 1. Every node has a value. 2. The value of any node is greater than the value of its left child and less than the value of its right child. (Like AVL, values must be unique) 3. Every node is colored either red or black.
Red Black Rules 4 - 6 Red Black Trees are binary trees with the following properties. • • • Every red node that is not a leaf has only black children. Every path from the root to a leaf contains the same number of black nodes. The root node is black.
Consider Insertion Into Red Black Trees • Tree Searching, Tree Insertions and Tree Deletions can be made to run in O(log(n)) for redblack trees. – This is not obvious and takes some planning to understand • To insert into a red-black tree, the insertion is done as you would with a normal binary search tree. – Just as with the AVL tree, a rotation will be required when the red-black structure is violated
Insertion Into Red Black Trees • Insertion of a node in a red-black tree can be done in O(log(n)) time. • We insert the new node into the tree as if it were an ordinary BST. We then color the node red. • Since the 6 Red Black properties are most surely not valid, we must have a Fix. It. Up, or Re. Balance. Tree, procedure to restore desired properties.
Right-Rotate (y) • Our basic operation for changing tree structure is called rotation: y x A C B x Right. Rotate(y) A y B • Preserves BST key ordering • O(1) time…just changes some pointers C
Left-Rotate (x) • Our basic operation for changing tree structure is called rotation: x A y Left. Rotate(x) x y B C A C B • Preserves BST key ordering • O(1) time…just changes some pointers
Red Black Trees: Rotation • Our basic operation for changing tree structure is called rotation: y x A C B x Right. Rotate(y) A Left. Rotate(x) y B • Preserves BST key ordering • O(1) time…just changes some pointers C
Insertion Into Red Black Trees 1. Every node has Add 1 To Tree a value. Now Add 2 2. The value of any node is greater than the value of its left child and less than the value of its right child. 3. Every node is colored either red or black. 4. Every red node that is not a leaf has only black children. 5. Every path from the root to a leaf contains the same number of black nodes. 6. The root node is
Insertion Into Red Black Trees 1. Every node has Add 2 To 1 a value. Now Add 5 2. The value of any node is greater than the value of its left child and less than the value of its right child. 3. Every node is colored either red or black. 4. Every red node that is not a leaf has only black children. 5. Every path from the root to a leaf contains the same number of black nodes. 6. The root node is
Insertion Into Red Black Trees 1. Every node has Add 5 To 1, 2 a value. Color the new node red. Left Rotate 1 Adjust The Colors 2. The value of any node is greater than the value of its left child and less than the value of its right child. 3. Every node is colored either red or black. 4. Every red node that is not a leaf has only black children. 5. Every path from the root to a leaf contains the same number of black nodes. 6. The root node is
Insertion Into Red Black Trees 1. Every node has Add 5 To Tree a value. Now Add 2 2. The value of any node is greater than the value of its left child and less than the value of its right child. 3. Every node is colored either red or black. 4. Every red node that is not a leaf has only black children. 5. Every path from the root to a leaf contains the same number of black nodes. 6. The root node is
Insertion Into Red Black Trees 1. Every node has Add 2 To 5 a value. Now Add 1 2. The value of any node is greater than the value of its left child and less than the value of its right child. 3. Every node is colored either red or black. 4. Every red node that is not a leaf has only black children. 5. Every path from the root to a leaf contains the same number of black nodes. 6. The root node is
Insertion Into Red Black Trees 1. Every node has Add 1 To 1, 5, 2 a value. Color the new node red. Right Rotate 5 Adjust The Colors 2. The value of any node is greater than the value of its left child and less than the value of its right child. 3. Every node is colored either red or black. 4. Every red node that is not a leaf has only black children. 5. Every path from the root to a leaf contains the same number of black nodes. 6. The root node is
http: //www. ececs. uc. edu/=franco/C 321/html/Red. Black/redblack. html Red-Black Trees BSTs with colored nodes. Coloring obeys several properties to be illustrated by following example: 4 2 1 8 3 6 9 7 12
Red-Black Trees All nodes with values are internal. All leaves are black. 4 2 1 8 3 6 9 7 12
Red-Black Trees The root is black. Restriction could be dropped, complicating operations. 4 2 1 8 3 6 9 7 12
Red-Black Trees For each node, every path to a leaf has the same number of black nodes. Red nodes have black children. 4 4 2 1 8 3 6 2 9 7 4 1 12 8 3 6 2 9 7 1 12 8 3 6 9 7 12
Red-Black Trees Typically don’t draw leaves. 4 4 2 1 8 3 6 2 9 7 1 12 8 3 6 9 7 12
2 -3 -4 & Red-Black Trees x x y y y x y z x z
Black Height Black-height(node) = # of black nodes on path from node to leaf, not counting node. 2 4 ? Values for example? 1 ? 2 1 8 3 6 9 7 0 12
Black Height Questions For a given black-height bh, what tree has max # of nodes? Complete tree, alternating red & black levels. bh h/2 Red nodes on any path h/2, since red node can’t have red child. Thus, black nodes on any path h/2. How can you relate a tree’s black-height bh & height h?
Black Height Lemma Subtree with root = node x has 2 bh(x)-1 internal x nodes. Prove by induction on height of x: Base case, height=0: x is leaf. bh(x)=0 Tree has 20 -1=0 internal nodes. x
Black Height Lemma Subtree with root = node x has 2 bh(x)-1 internal x nodes. Prove by induction on height of x: Inductive case, height>0: x is has two children. Each has black height of bh(x) or bh(x)-1. Inductively, each has 2 bh(x)-1 -1 internal nodes. Has 2 (2 bh(x)-1 -1)+1 = 2 bh(x)-1 internal nodes. y x z
Height Theorem Tree with n internal nodes has height 2 lg(n+1). Proof: Tree has n 2 bh(root)-1 internal nodes. Lemma bh(root) lg(n+1) Algebra h/2 bh(root) Shown previously Traversals require O(log n) time: Search Max, Min Successor, Predecessor
Insertion Algorithm Outline Put new node at bottom of tree, in BST order. Color it red to preserve black height. There could be a red parent with a red child. While there is, propagate this conflict up the tree by recolorings & rotations.
RB-INSERT(T, z) 1 y = nil[T] 2 x = root[T] 3 while x <> nil[T] 4 do y = x 5 if key[z] < key[x] 6 then x = left[x] 7 else x = right[x] 8 p[z] = y 9 if y = nil[T] 10 then root[T] = z 11 else if key[z] < key[y] 12 then left[y] = z 13 else right[y] = z 14 left[z] = nil[T] 15 right[z] = nil[T] 16 color[z] = RED 17 RB-INSERT-FIXUP(T, z)
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]]] 4 if color[y] = RED 5 then color[p[z]] = BLACK 6 color[y] = BLACK 7 color[p[p[z]]] = RED 8 z = p[p[z]] [> Case I 9 else if z = right[p[z]] 10 then z = p[z] I 1 LEFT-Ro. TATE(T, z) 12 color[p[z]] = BLACK 13 color[p[p[z]]] = RED 14 RIGHT-Ro. TATE(T, p[p[z]]) 15 else (same as then clause with "right" and "left" exchanged) 16 color[root[T]] = BLACK
LEFT-ROTATE(T, X) 1 y = right[x] 2 right[x] = left[y] 3 if left[y] <> nil[T 4 then p[left[y]] = x 5 p[y] = p[x] 6 ifp[x] =nil[T] 7 then root[T] = y 8 else if x = left[p[x]] 9 then left[p[x ]] = y 10 else right[p[x]] = y 11 left[y] = x 12 p[x] = y
Insertion Example 10 Insert 10, 3, 15, 20, 1 5 1 15 20
Insertion Example: Case 0 10 10 3 1 15 20 3 Insert 5 1 15 5 20 Color red is dictated by properties. All properties satisfied. Easy case.
Insertion Example: Case 1 10 3 1 10 15 5 Insert 7 3 1 20 15 5 20 Red red parent has red child. Black parent has inconsistent black height. 7 10 Algorithm: Color red, then fix by recoloring. 3 Recolor 1 15 5 20 7 Recolor parent, uncle to black. Recolor grandparent to red.
Insertion Example: Case 3 10 10 3 1 15 5 3 Insert 8 20 7 1 Previous recoloring doesn’t work. Uncle (a leaf) already black. 15 5 20 7 10 8 Recolor parent black. Recolor grandparent red. Rotate grandparent. Recolor & Rotate 3 1 15 7 5 8 20
Insertion Example: Case 1 10 3 1 10 Insert 9 15 7 1 20 10 5 8 3 Recolor 3 1 7 20 5 8 15 7 15 Uncle red, as in 1 st recoloring, so… Recolor parent, uncle to black. Recolor grandparent to red. 9 20 5 8 9 Grandparent & its parent might now both be red. Continue.
Insertion Example: Case 2 10 3 1 15 7 20 Uncle of current node is black, so… Need to recolor parent & grandparent. 5 8 But current node is a right child while parent is a left child. Want both to be same side. 10 9 Rotate 15 7 3 1 5 8 20 9 Can’t eliminate red-red problem, but prepares for…
Insertion Example: Case 3 10 15 7 3 1 5 7 8 20 9 3 Recolor & Rotate 1 10 5 8 15 9 20
Insertion Algorithm 1 Put new node at bottom of tree, in BST order. Color it red to preserve black height. While current node’s parent is red, If uncle is red, 2 Recolor parent & uncle to black. Recolor grandparent to red. Current node = grandparent. If uncle is black, 3 Right uncle Left Right uncle If current node is a right child, Current node = parent. Rotate current node. Recolor parent as black.
Insertion Analysis • Correctness: – Operations maintain invaraints. • Argued through example. See [CLRS] for details. • Running-time: – Insertion at bottom: • Constant work per level traversing down tree. • O(log n) – Fixup: • Constant work, including at most 1 rotation per level, traversing up tree. • O(log n)
rb. Insert(x) tree. Insert(x); x->color = RED; // Move violation of #3 up tree, maintaining #4 as invariant: while (x!=root && x->p->color == RED) if (x->p == x->p->p->left) y = x->p->p->right; if (y->color == RED) x->p->color = BLACK; y->color = BLACK; Case 1 x->p->p->color = RED; x = x->p->p; else // y->color == BLACK if (x == x->p->right) x = x->p; Case 2 left. Rotate(x); x->p->color = BLACK; x->p->p->color = RED; Case 3 right. Rotate(x->p->p); else // x->p == x->p->p->right (same as above, but with “right” & “left” exchanged)
rb. Insert(x) tree. Insert(x); x->color = RED; // Move violation of #3 up tree, maintaining #4 as invariant: while (x!=root && x->p->color == RED) if (x->p == x->p->p->left) y = x->p->p->right; if (y->color == RED) x->p->color = BLACK; y->color = BLACK; Case 1: uncle is RED x->p->p->color = RED; x = x->p->p; else // y->color == BLACK if (x == x->p->right) x = x->p; Case 2 left. Rotate(x); x->p->color = BLACK; x->p->p->color = RED; Case 3 right. Rotate(x->p->p); else // x->p == x->p->p->right (same as above, but with “right” & “left” exchanged)
RED BLACK TREES Case 1 a: Father and Uncle are Red , problem node is right child C C Recolor it to After Recoloring BLACK A B d D A D e B a d a b c e
RED BLACK TREES Case 1 b: Father and Uncle are Red , problem node is left child C BLACK After Recoloring B B D A A c d b D c e a a Recolor it to C b d e
RED BLACK TREES Case 2 a: Father red and Uncle Black, problem node is left child B C D B A a c b d After Rotation C A D a b c d
RED BLACK TREES Case 2 b: Father red and Uncle Black, problem node is right child C C After Rotation D A B B A d c a b c D a b d apply 2 a for the above tree
RED BLACK TREES Example: 11 Apply 11 Case 1 b 2 14 7 1 2 14 15 7 1 5 Insert Node 4 4 8 5 4 15 8
RED BLACK TREES 11 2 14 7 1 11 Apply Case 2 b 7 15 8 2 5 8 1 4 5 4 14 15
http: //www. ececs. uc. edu/=franco/C 321/html/Red. Black/redblack. html
Ensuring tree height h = O(log n) Red Black Trees
Red Black Properties • A binary search tree where – Every node is either “red” or “black” • For consistency we count “null” pointers as if they were “black” nodes. This means that an empty tree (one where the root is null) satisfies the definition (it’s black). – If a node is red, then both children are black • Another reason for “null” pointers being considered black – For any node, x, in the tree. All paths from x to a leaf have exactly the same number of black nodes.
Red/Black Tree has height O(log n) • Let the “black-height” of a node x be the number of black nodes that are descendants of x. • Then, for any node x, the subtree rooted at x has at least 2 bh(x) -1 nodes. – Proof, by induction on the height of node x. • If the height of x is 0, then the bh is zero, and 20 -1 is 0. Of course, if the height of x is 0 then there are no nodes in the tree (x is an empty subtree). • If the height of x is k, and the bh of x is b (b < k), then consider each of the two children of x (either of which may be null). The black height of the child must be at least b – 1 (which happens if the child is black). By the inductive hypothesis, the subtree rooted at each child has 2 b-1 -1 nodes. If we add up the number of nodes in both children, we have 2 * (2 b-1 – 1), or 2 b – 2. When we add in the node x we get 2 b – 1. So the number of nodes in the subtree rooted at x is at least 2 b-1 • Note that bh > h/2. So a tree with height h must have at least 2 h/2 -1 nodes in it. i. e. , 2 h/2 -1 ≤ n. • Therefore (taking the log base 2 of both sides) h < 2 log 2(n+1)
Huh? Doesn’t that work for any tree? • That proof kinda stinks of the “let’s prove zero equals one” sort of proofs… in particular, it seems that the technique could be used to prove that all trees are balanced. • The inductive proof relies on the black height being “well defined” for any node. – The height is defined as the longest path to a leaf – The black height is the same for all paths to a leaf. • That’s why you cannot prove that any tree of height h has at least Ω(2 h) nodes in it.
Making Red/Black Trees • The basic idea of a Red/Black tree is to use the insert and remove operations of an ordinary binary search tree. – But this may result in violating the red/black properties • So, we’ll “fixup” the tree after each insert/remove
Rotations • A “right rotate” will interchange a node with its left child. The child will become the parent, and the parent will become a child. – The parent becomes the right child of the child. • The old “right grandchild” becomes the left child of the parent • A “left rotate” will interchange a node with its right child – The parent becomes the left child of the child • The old “left grandchild” becomes the right child of the parent • Note that these operations are exact opposites (inverses) of each other. • Note also that Rotations do not affect the BST properties (although they will almost certainly affect the red/black properties).
Insert • Insert the value normally, and make the new node “red” – We have not changed the black height of any node in the tree. – However, we may have created a red node with a red parent (and this is bad). • As we “fixup” we’ll always have a pointer to a red node. We’ll always know that the black height is OK, and the only problem we need to worry about is that the parent of this red node is also red.
Fixup • • Let c (child) be the red node we inserted Let p (parent) be the parent of c Let gp (grandparent) be the parent of p Let u (uncle) be the child of gp that is not equal to p • If p->color == black, we’re done. So, assume p>color == red. – We know, therefore, that gp->color == black. • Two interesting cases – Uncle is red (easy), or uncle is black (harder)
Uncle is red • If the grandparent is black, the parent is red and the uncle is red, then – we would not change the black height by making the grandparent red and the parent (and uncle) black. – We may, however, have introduced a new problem where the grandparent is now red, and its parent is also red (the great-grandparent). • So, if the uncle is red, make it and the parent black. Make the grandparent red, and then repeat fixup where we treat the grandparent as the next “child”.
Uncle is Black • Make the parent black – But this increases the number of black nodes along the path to the child. • Make the grandparent red – This fixes the problem with the path from the root to the child, but it decreases (breaks) the number of black nodes on the path from the root to the uncle • Rotate around the grandparent and parent – So that the path from the root to the uncle now passes through both the parent and the grandparent – (and the path from the root to the child no longer passes through the grandparent).
Case Analysis • Coding this up requires six cases. Three cases are for when the parent is the left child of the grandparent, and three (perfectly symmetric) cases for when the parent is the right child of the grandparent. • Of the remaining three cases, “uncle is red” is one case. • Two cases are required for “uncle is black” depending on whether the path from grandparent to child is “straight” or “crooked” – If the path is “crooked” then we’ll need to rotate first around the parent and child, and then perform the rotation around the parent and grandparent.
“Root is Black” Sentinel • Once we reach the root of the tree, we’re done. • If we can ensure that the root is always black, then we don’t need to worry about the special case of reaching the root in fixup. – Fixup stops whenever the next “child” is black, or when the parent is black. • It’s easy (and always correct) to simply make the root black as the last step in any insert/remove operation.
Time Complexity • Fixup runs in a loop. Each iteration of the loop we do – O(1) work in case analysis – O(1) work recoloring nodes (“uncle is red” case) – O(1) work performing rotations (at worst 2 rotations) • Each iteration of the loop we either terminate (always the case after a rotation), or we set “child” equal to grandparent – i. e. , each iteration of the loop uses a node with height less than the previous iteration. • Since height must decrease each iteration, we can do at most h iterations. Since h = O(log n), we do O(log n) iterations with O(1) work each iteration.
- Slides: 65