1 data structures and algorithms searching red-black and other dynamically balancedtrees
TRANSCRIPT
1
Data Structures and Algorithms
Searching
Red-Black and Other Dynamically BalancedTrees
2
Red/Black Trees• Red/Black trees provide another alternative implementation of
balanced binary search trees
• A red/black tree is a balanced binary search tree where each node stores a color (usually implemented as a boolean)
• The following rules govern the color of a node:
• The root is black• All children of a red node are black• Every path from the root to a leaf contains the same number of
black nodes
3
FIGURE 13.16 Valid red/black trees
4
Insertion into Red/Black Trees
• The color of a new element is set to red• Once the new element has been inserted, the tree is
rebalanced/recolored as needed to to maintain the properties of a red/black tree
• This process is iterative beginning at the point of insertion and working up the tree toward the root
• The process terminates when we reach the root or when the parent of the current element is black
5
Insertion into Red/Black Trees
• In each iteration of the rebalancing process, we will focus on the color of the sibling of the parent of the current node
• There are two possibilities for the parent of the current node:
• The parent could be a left child• The parent could be a right child
• The color of a null node is considered to be black
6
Insertion into Red/Black Trees
• In the case where the parent of the current node is a right child, there are two cases
• Leftaunt.color == red• Leftaunt.color == black
• If leftaunt.color is red then the processing steps are:
7
FIGURE 13.17 Red/black tree after insertion
8
Insertion into Red/Black Trees
• If leftaunt.color is black, we first must check to see if current is a left child or a right child
• If current is is a left child, then we must set current equal to current.parent and then rotate current.left to the right
• The we continue as if current were a right child to begin with:
9
Insertion into Red/Black Trees
• In the case where the parent of current is a left child, there are two cases: either
• rightuncle.color == red or rightuncle.color == black
• If rightuncle.color == red then the processing steps are:
10
FIGURE 13.18 Red/black tree after insertion
11
Insertion into Red/Black Trees
• If rightuncle.color == black then we first need to check to see if current is a left or right child
• If current is a right child then we set current equal to current.parent then rotate current.right or the left around current
• We then continue as if current was left child to begin with:
12
Element Removal from Red/Black Trees
• As with insertion, the tree will need to be rebalanced/recolored after the removal of an element
• Again, the process is an iterative one beginning at the point of removal and continuing up the tree toward the root
• This process terminates when we reach the root or when current.color == red
13
Element Removal from Red/Black Trees
• Like insertion, the cases for removal are symmetrical depending upon whether current is a left or right child
• In insertion, we focused on the color of the sibling of the parent
• In removal, we focus on the color of the sibling of current keeping in mind that a null node is considered to be black
14
Element Removal from Red/Black Trees
• We will only examine the cases where current is a right child, the other cases are easily derived
• If the sibling’s color is red then we begin with the following steps:
15
FIGURE 13.19 Red/black tree after removal
16
Element Removal from Red/Black Trees
• Next our processing continues regardless of whether the original sibling was red or black
• Now our processing is divided into two cases based upon the color of the children of the sibling
• If both of the children of the sibling are black then:
17
Element Removal from Red/Black Trees
• If the children of the sibling are not both black, then we check to see if the left child of the sibling is black
• If it is, then we must complete the following steps before continuing:
18
Element Removal from Red/Black Trees
• Then to complete the process in the case when both of the children of the sibling are not black:
19
Searching - Re-visited
• Binary tree O(log n) if it stays balanced• Simple binary tree good for static
collections• Low (preferably zero) frequency of
insertions/deletions but my collection keeps changing!
• It’s dynamic• Need to keep the tree balanced
• First, examine some basic tree operations• Useful in several ways!
20
Tree Traversal
• Traversal = visiting every node of a tree• Three basic alternatives Pre-order
• Root• Left sub-tree• Right sub-tree
x A + x + B C x D E F
L R L L R
21
Tree Traversal
• Traversal = visiting every node of a tree• Three basic alternatives In-order
• Left sub-tree• Root• Right sub-tree
A x B + C x D x E + F
L RL
11
22
Tree Traversal• Traversal = visiting every node of a tree• Three basic alternatives
Post-order
• Left sub-tree• Right sub-tree• Root
A B C + D E x x F + x
L R
L
11
23
Tree Traversal
Post-order• Left sub-tree• Right sub-tree• Root
Reverse-Polish
• Normal algebraic form
= which traversal?
(A (((BC+)(DEx) x) F +)x )
11
(A x ((( B+C) (DxE)) +F))
24
• Binary search tree
• Produces a sorted list by in-order traversal
• In order: A D E G H K L M N O P T V
1)public void 1)public void inorderPrint(BinaryNode t inorderPrint(BinaryNode t ) ) 2) if (left != null)2) if (left != null) 3) 3) inorderPrint(t.left );inorderPrint(t.left ); 4) 4) System.out.println(data);System.out.println(data); 5) if (right != null)5) if (right != null)6inorderPrint(t.right );inorderPrint(t.right );7}}
25
Trees - Searching
• Binary search tree• Preserving the order• Observe that this transformation preserves the
search tree
26
Trees - Searching
• Binary search tree• Preserving the order• Observe that this transformation preserves the
search tree
• We’ve performed a rotation of the sub-tree about the T and O nodes
27
Trees - Rotations
• Binary search tree• Rotations can be either left- or right-rotations
• For both trees: the inorder traversal is A x B y C
Right_rotate
left_rotate
28
Trees - Rotations
• Binary search tree• Rotations can be either left- or right-rotations
• Note that in this rotation, it was necessary to move B from the right child of x to the left child of y
Right_rotate
Left_rotate
29
Trees - Red-Black Trees
• A Red-Black Tree• Binary search tree• Each node is “coloured” red or black
• An ordinary binary search tree with node colorings to make a red-black tree
30
Trees - Red-Black Trees
• A Red-Black Tree• Every node is RED or BLACK• Every leaf is BLACK
When you examinerb-tree code, you will
see sentinel nodes (black) added as the leaves.
They contain no data.Sentinel nodes (black)
31
Trees - Red-Black Trees
• A Red-Black Tree• Every node is RED or BLACK• Every leaf is BLACK• If a node is RED,
then both children are BLACK
This implies that no pathmay have two adjacent
RED nodes.(But any number of BLACK
nodes may be adjacent.)
32
Trees - Red-Black Trees
• A Red-Black Tree• Every node is RED or BLACK
• Every leaf is BLACK
• If a node is RED, then both children are BLACK
• Every path from a node to a leaf contains the same number of BLACK nodes From the root,
there are 3 BLACK nodes on every path
33
Trees - Red-Black Trees
• A Red-Black Tree• Every node is RED or BLACK• Every leaf is BLACK
• If a node is RED, then both children are BLACK
• Every path from a node to a leaf contains the same number of BLACK nodes
The length of this path is theblack height of the tree
34
Trees - Red-Black Trees
• Lemma
A RB-Tree with n nodes has height 2 log(n+1)
• Essentially, height 2 black height
• Search time O( log n )
35
Same as abinary tree
with these twoattributes
added
Trees - Red-Black Trees
• Data structure
• As we’ll see, nodes in red-black trees need to know their parents,
• so we need this data structure
class RedBlackNode { Colour red, black ; Object data; RedBlackNode left, right, parent; }
36
Trees - Insertion
• Insertion of a new node• Requires a re-balance of the tree
Label the current node x
Insert node 4
Mark it red
37
RedBlackInsert( Tree T, Node x ) { /* Insert in the tree in the usual way */ tree_insert( T, x ); /* Now restore the red-black property */ x.colour = red; while ( (x != T.root) && (x.parent.colour == red) ) {while ( (x != T.root) && (x.parent.colour == 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' *//* If x's parent is a left, y is x's right 'uncle' */ y = x.parent.parent.right;y = x.parent.parent.right; if ( y.colour == red ) {if ( y.colour == red ) { /* case 1 - change the colours *//* case 1 - change the colours */ x.parent.colour = black;x.parent.colour = black; y.colour = black;y.colour = black; x.parent.parent.colour = red;x.parent.parent.colour = red; /* Move x up the tree *//* Move x up the tree */ x = x.parent.parent;x = x.parent.parent;
Trees - Insertion
While we haven’t reached the rootand x’s parent is red
x.parent
38
RedBlackInsert( Tree T, Node x ) { /* Insert in the tree in the usual way */ tree_insert( T, x ); /* Now restore the red-black property */ x.colour = red; while ( (x != T.root) && (x.parent.colour == red) ) { if ( x.parent == x.parent.parent.left ) { /* If x's parent is a left, y is x's right 'uncle' *//* If x's parent is a left, y is x's right 'uncle' */ y = x.parent.parent.right;y = x.parent.parent.right; if ( y.colour == red ) {if ( y.colour == red ) { /* case 1 - change the colours *//* case 1 - change the colours */ x.parent.colour = black;x.parent.colour = black; y.colour = black;y.colour = black; x.parent.parent.colour = red;x.parent.parent.colour = red; /* Move x up the tree *//* Move x up the tree */ x = x.parent.parent;x = x.parent.parent;
Trees - Insertion
If x is to the left of it’s grandparent
x.parent
x.parent.parent
39
Trees - Insertion
y is x’s right uncle
x.parent
x.parent.parent
right “uncle”
40
Trees - Insertion
x.parent
x.parent.parent
right “uncle”
If the uncle is red, change the colours of y, the grand-parent and the parent
41
Trees - Insertion
42
Trees - Insertion
while ( (x != T.root) && (x.parent.colour == red) ) { 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.colour == red ) { /* case 1 - change the colours */ x.parent.colour = black; y.colour = black; x.parent.parent.colour = red; /* Move x up the tree */ x = x.parent.parent;
x’s parent is a left again,mark x’s uncle
but the uncle is black this time
New x
43
Trees - Insertion
while ( (x != T.root) && (x.parent.colour == red) ) { 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.colour == red ) { /* case 1 - change the colours */ x.parent.colour = black; y.colour = black; x.parent.parent.colour = 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 );
.. but the uncle is black this timeand x is to the right of it’s parent
44
Trees - Insertion
while ( (x != T.root) && (x.parent.colour == red) ) { 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.colour == red ) { /* case 1 - change the colours */ x.parent.colour = black; y.colour = black; x.parent.parent.colour = 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 );
.. So move x up and rotate about x as root ...
45
Trees - Insertion
while ( (x != T.root) && (x.parent.colour == red) ) { 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.colour == red ) { /* case 1 - change the colours */ x.parent.colour = black; y.colour = black; x.parent.parent.colour = 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 );
46
Trees - Insertion
while ( (x != T.root) && (x.parent.colour == red) ) { 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.colour == red ) { /* case 1 - change the colours */ x.parent.colour = black; y.colour = black; x.parent.parent.colour = 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 );
.. but x’s parent is still red ...
47
Trees - Insertion
while ( (x != T.root) && (x.parent.colour == red) ) { 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.colour == red ) { /* case 1 - change the colours */ x.parent.colour = black; y.colour = black; x.parent.parent.colour = 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 );
.. The uncle is black ..
.. and x is to the left of its parent
uncle
48
Trees - Insertion
while ( (x != T.root) && (x.parent.colour == red) ) { 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.colour == red ) { /* case 1 - change the colours */ x.parent.colour = black; y.colour = black; x.parent.parent.colour = 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 );
else { /* case 3 */ x.parent.colour = black; x.parent.parent.colour = red; right_rotate( T, x.parent.parent ); }
.. So we have the final case ..
49
Trees - Insertion
while ( (x != T.root) && (x.parent.colour == red) ) { 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.colour == red ) { /* case 1 - change the colours */ x.parent.colour = black; y.colour = black; x.parent.parent.colour = 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 );
else { /* case 3 */ x.parent.colour = black; x.parent.parent.colour = red; right_rotate( T, x.parent.parent ); }
.. Change coloursand rotate ..
50
Trees - Insertion
while ( (x != T.root) && (x.parent.colour == red) ) { 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.colour == red ) { /* case 1 - change the colours */ x.parent.colour = black; y.colour = black; x.parent.parent.colour = 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 );
else { /* case 3 */ x.parent.colour = black; x.parent.parent.colour = red; right_rotate( T, x.parent.parent ); }
51
Trees - Insertion
while ( (x != T.root) && (x.parent.colour == red) ) { 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.colour == red ) { /* case 1 - change the colours */ x.parent.colour = black; y.colour = black; x.parent.parent.colour = 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 );
else { /* case 3 */ x.parent.colour = black; x.parent.parent.colour = red; right_rotate( T, x.parent.parent ); }
This is now a red-black tree ..So we’re finished!
52
Trees - Insertion
while ( (x != T.root) && (x.parent.colour == red) ) { if ( x.parent == x.parent.parent.left ) {else ....
There’s an equivalent set ofcases when the parent is tothe right of the grandparent!
53
Red-black trees - Analysis
• Addition
• Insertion Comparisons O(log n)
• Fix-up• At every stage,
x moves up the tree
at least one level O(log n)
• Overall O(log n)• Deletion
• Also O(log n)• More complex• ... but gives O(log n) behaviour in dynamic cases
54
Red Black Trees - What you need to know?• You need to know
• The algorithm exists• What it’s called• When to use it
• ie what problem does it solve?
• Its complexity• Basically how it works• Where to find an implementation
• How to transform it to your application