Red-black Trees

COMP2521 20T2 ♢ Red-black Trees [0/18]
❖ Red-Black Trees

Red-black trees are a representation of 2-3-4 trees using BST nodes.

Link types: Advantages:
COMP2521 20T2 ♢ Red-black Trees [1/18]
❖ ... Red-Black Trees

Definition of a red-black tree

Balanced red-black tree Insertion algorithm: avoids worst case O(n) behaviour

Search algorithm: standard BST search

COMP2521 20T2 ♢ Red-black Trees [2/18]
❖ ... Red-Black Trees

Representing 4-nodes in red-black trees:

[Diagram:Pics/234-rb-nodes.png]


Some texts colour the links rather than the nodes.

COMP2521 20T2 ♢ Red-black Trees [3/18]
❖ ... Red-Black Trees

Representing 3-nodes in red-black trees (two possibilities):

[Diagram:Pics/234-rb-nodes2.png]

COMP2521 20T2 ♢ Red-black Trees [4/18]
❖ ... Red-Black Trees

Equivalent trees (one 2-3-4, one red-black):

[Diagram:Pics/234-rb-tree2.png]

COMP2521 20T2 ♢ Red-black Trees [5/18]
❖ ... Red-Black Trees

Red-black tree implementation:

typedef enum {RED,BLACK} Colour;
typedef struct node *RBTree;
typedef struct node {
   int    data;    // actual data
   Colour colour;  // relationship to parent
   RBTree left;    // left subtree
   RBTree right;   // right subtree
} node;

#define colour(tree) ((tree) != NULL && (tree)->colour)
#define isRed(tree)  ((tree) != NULL && (tree)->colour == RED)

RED = node is part of the same 2-3-4 node as its parent (sibling)

BLACK = node is a child of the 2-3-4 node containing the parent

COMP2521 20T2 ♢ Red-black Trees [6/18]
❖ ... Red-Black Trees


New nodes are always red ...

RBTree newNode(Item it) {
   RBTree new = malloc(sizeof(Node));
   assert(new != NULL);
   data(new) = it;
   color(new) = RED;
   left(new) = right(new) = NULL;
   return new;
}


.. because they're always inserted into a leaf node

COMP2521 20T2 ♢ Red-black Trees [7/18]
❖ ... Red-Black Trees

Node.red allows us to distinguish links

[Diagram:Pics/red-black-equiv.png]

COMP2521 20T2 ♢ Red-black Trees [8/18]
❖ Searching in Red-black Trees

Search method is standard BST search:

searchRedBlack(tree,item):
|  Input  tree, item
|  Output true if item found in tree,
|         false otherwise
|
|  if tree is empty then
|     return false
|  else if item < data(tree) then
|     return SearchRedBlack(left(tree),item)
|  else if item > data(tree) then
|     return SearchRedBlack(right(tree),item)
|  else  // found
|    return true
|  end if

COMP2521 20T2 ♢ Red-black Trees [9/18]
❖ Insertion in Red-Black Trees


Insertion is more complex than for standard BSTs

Several cases to consider depending on colour/direction combinations
COMP2521 20T2 ♢ Red-black Trees [10/18]
❖ ... Insertion in Red-Black Trees


High-level description of insertion algorithm:

insertRedBlack(tree,item):
|  Input  red-black tree, item
|  Output tree with item inserted
|
|  tree = insertRB(tree,item,false)
|  colour(tree) = BLACK
|  return tree

This function acts as a "wrapper" around the recursive function.

Having restructured the tree, it then makes the root node BLACK

COMP2521 20T2 ♢ Red-black Trees [11/18]
❖ ... Insertion in Red-Black Trees

Overview of the recursive function ...

insertRB(tree,item,inRight):
|  Input  tree, item, inRight
|         // inRight = direction of last branch
|  Output tree with item inserted
|
|  if tree is empty then return newNode(item)
|  if data(tree) = item then return tree
|  if isRed(left(tree)) ∧ isRed(right(tree)) then
|     split 4-node
|  end if
|  recursive insert cases (cf. regular BST)
|  re-arrange links/colours after insert
|  return modified tree
COMP2521 20T2 ♢ Red-black Trees [12/18]
❖ ... Insertion in Red-Black Trees

Splitting a 4-node, in a red-black tree:

[Diagram:Pics/red-black-split.png]

Algorithm:

if isRed(left(tree)) ∧ isRed(right(tree)) then
   colour(tree) = RED
   colour(left(tree)) = BLACK
   colour(right(tree)) = BLACK
end if
COMP2521 20T2 ♢ Red-black Trees [13/18]
❖ ... Insertion in Red-Black Trees

Simple recursive insert (a la BST):

[Diagram:Pics/red-black-ins-easy.png]

Algorithm:

if item < data(tree)) then
   left(tree) = insertRB(left(tree),item,false)
   re-arrange links/colours after insert
else        // item larger than data in root
   right(tree) = insertRB(right(tree),item,true)
   re-arrange links/colours after insert
end if
COMP2521 20T2 ♢ Red-black Trees [14/18]
❖ ... Insertion in Red-Black Trees

Re-arrangement #1: two successive red links = newly-created 4-node

[Diagram:Pics/red-black-insert-1.png]

Algorithm:

if isRed(left(tree)) ∧ isRed(left(left(tree))) then
   tree=rotateRight(tree)
   colour(tree)=BLACK
   colour(right(tree))=RED
end if
COMP2521 20T2 ♢ Red-black Trees [15/18]
❖ ... Insertion in Red-Black Trees

Re-arrangement #2: "normalise" direction of successive red links

[Diagram:Pics/red-black-insert-2.png]

Algorithm:

if inRight ∧ isRed(tree) ∧ isRed(left(tree)) then
   tree=rotateRight(tree)
end if
COMP2521 20T2 ♢ Red-black Trees [16/18]
❖ ... Insertion in Red-Black Trees

Example of insertion, starting from empty tree:

22, 12, 8, 15, 11, 19, 43, 44, 45, 42, 41, 40, 39


To see how built:   www.cs.usfca.edu/~galles/visualization/RedBlack.html

COMP2521 20T2 ♢ Red-black Trees [17/18]
❖ Red-black Tree Performance


Cost analysis for red-black trees:

Only disadvantage is complexity of insertion/deletion code.

Note: red-black trees were popularised by Sedgewick.

COMP2521 20T2 ♢ Red-black Trees [18/18]


Produced: 18 Jun 2020