Red-Black Tree
A Red-Black Tree is a self-balancing BST that uses node coloring (red/black) to maintain balance. It is more flexible than an AVL Tree, so it is faster for insert and delete operations.
Red-Black Tree Properties
- Every node is either red or black.
- The root is always black.
- All leaves (None) are considered black.
- If a node is red, its children must be black (no two reds in a row).
- Every path from the root to a leaf contains the same number of black nodes.
Rotations and Recoloring
Red-Black Trees use:
- Recoloring: Changing a node's color.
- Rotation: Left/right rotations, just like in AVL Trees.
RED = True
BLACK = False
class RBNode:
def __init__(self, val):
self.val = val
self.left = None
self.right = None
self.parent = None
self.color = RED
Insert
When inserting a new node (always red), there are several cases:
Case 1: Uncle is red
Recolor the parent, uncle, and grandparent.
Case 2: Uncle is black, zig-zag
Rotate to turn it into case 3.
Case 3: Uncle is black, zig-zig
Rotate the grandparent, then recolor.
class RedBlackTree:
def __init__(self):
self.NIL = RBNode(None)
self.NIL.color = BLACK
self.root = self.NIL
def insert(self, val):
node = RBNode(val)
node.left = self.NIL
node.right = self.NIL
y = None
x = self.root
while x != self.NIL:
y = x
if node.val < x.val:
x = x.left
else:
x = x.right
node.parent = y
if not y:
self.root = node
elif node.val < y.val:
y.left = node
else:
y.right = node
if not node.parent:
self.root = node
node.color = BLACK
return
if not node.parent.parent:
return
self._fix_insert(node)
def _fix_insert(self, k):
while k.parent and k.parent.color == RED:
if k.parent == k.parent.parent.right:
u = k.parent.parent.left
if u.color == RED:
u.color = BLACK
k.parent.color = BLACK
k.parent.parent.color = RED
k = k.parent.parent
else:
if k == k.parent.left:
k = k.parent
self._right_rotate(k)
k.parent.color = BLACK
k.parent.parent.color = RED
self._left_rotate(k.parent.parent)
else:
u = k.parent.parent.right
if u.color == RED:
u.color = BLACK
k.parent.color = BLACK
k.parent.parent.color = RED
k = k.parent.parent
else:
if k == k.parent.right:
k = k.parent
self._left_rotate(k)
k.parent.color = BLACK
k.parent.parent.color = RED
self._right_rotate(k.parent.parent)
if k == self.root:
break
self.root.color = BLACK
AVL vs Red-Black Tree
| Aspect | AVL | Red-Black |
|---|---|---|
| Balance | More balanced | Slightly looser |
| Search | Faster | Slightly slower |
| Insert/Delete | More rotations | Fewer rotations |
| Usage | Database indexes | Java TreeMap, C++ map |
Time Complexity
| Operation | Time |
|---|---|
| Insert | O(log n) |
| Search | O(log n) |
| Delete | O(log n) |
Red-Black Trees are used in many standard libraries. Now let's study Heaps for prioritized data.