1 data structures and algorithms searching red-black and other dynamically balancedtrees

Post on 04-Jan-2016

213 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

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

top related