Skip to main content

Red-Black Tree

tmdeveloper007
EditReport

Red-Black Tree is a self-balancing binary search tree that uses color attributes (red/black) on nodes to maintain approximate balance. It guarantees O(logn)O(\log n) worst-case time for search, insertion, and deletion operations.

Red-Black trees are widely used in practice: they are the underlying data structure for Java's TreeMap, C++'s std::map and std::set, and the Linux kernel's completely fair scheduler.

Key Feature

Red-Black trees maintain balance through five properties rather than strict height constraints. This makes insertions and deletions cheaper than AVL trees while still guaranteeing logarithmic performance.


Red-Black Tree Properties

A binary search tree is a Red-Black tree if it satisfies the following properties:

  1. Every node is either red or black.
  2. The root is black.
  3. All leaves (NIL/null children) are black.
  4. Red nodes cannot have red children (no two consecutive red nodes).
  5. Every path from a node to its descendant NIL leaves has the same number of black nodes (black-height).

These five properties guarantee that the height of the tree is at most 2 * log2(n+1)log_2(n + 1), ensuring O(logn)O(\log n) operations.


Rotations and Recoloring

Red-Black trees use two operations to restore balance after insertions and deletions:

Left Rotation

p q
/ \ / \
x q => p r
/ \ / \
y r x y

Right Rotation

Mirror of left rotation.

Recoloring

Change node colors (typically when a red-red conflict occurs and the uncle is red).


Insertion

New nodes are always inserted as red nodes. If this violates the red-black properties, fix-up operations restore balance.

Fix-Up Cases

CaseParentUncleAction
1RedRedRecolor parent/uncle to black, grandparent to red
2RedBlack (zig-zag)Rotate parent in direction of grandparent
3RedBlack (straight)Rotate grandparent in opposite direction

Complexity Analysis

OperationTime ComplexityNotes
SearchO(logn)O(\log n)Worst-case guaranteed
InsertO(logn)O(\log n)At most 2 rotations + recolorings
DeleteO(logn)O(\log n)At most 3 rotations
SpaceO(n)O(n)One extra bit per node

Implementation

Python

class RBNode:
def __init__(self, key, color='RED'):
self.key = key
self.color = color
self.left = None
self.right = None
self.parent = None

BLACK = 'BLACK'
RED = 'RED'

class RedBlackTree:
def __init__(self):
self.NIL = RBNode(key=None, color=BLACK)
self.NIL.left = self.NIL.right = self.NIL
self.root = self.NIL

def left_rotate(self, x):
y = x.right
x.right = y.left
if y.left != self.NIL:
y.left.parent = x
y.parent = x.parent
if x.parent is None:
self.root = y
elif x == x.parent.left:
x.parent.left = y
else:
x.parent.right = y
y.left = x
x.parent = y

def right_rotate(self, x):
y = x.left
x.left = y.right
if y.right != self.NIL:
y.right.parent = x
y.parent = x.parent
if x.parent is None:
self.root = y
elif x == x.parent.right:
x.parent.right = y
else:
x.parent.left = y
y.right = x
x.parent = y

def insert_fixup(self, z):
while z.parent and z.parent.color == RED:
if z.parent == z.parent.parent.left:
y = z.parent.parent.right
if y.color == RED:
z.parent.color = BLACK
y.color = BLACK
z.parent.parent.color = RED
z = z.parent.parent
else:
if z == z.parent.right:
z = z.parent
self.left_rotate(z)
z.parent.color = BLACK
z.parent.parent.color = RED
self.right_rotate(z.parent.parent)
else:
y = z.parent.parent.left
if y.color == RED:
z.parent.color = BLACK
y.color = BLACK
z.parent.parent.color = RED
z = z.parent.parent
else:
if z == z.parent.left:
z = z.parent
self.right_rotate(z)
z.parent.color = BLACK
z.parent.parent.color = RED
self.left_rotate(z.parent.parent)
self.root.color = BLACK

def insert(self, key):
z = RBNode(key)
z.left = z.right = self.NIL
y = None
x = self.root
while x != self.NIL:
y = x
if z.key < x.key:
x = x.left
else:
x = x.right
z.parent = y
if y is None:
self.root = z
elif z.key < y.key:
y.left = z
else:
y.right = z
self.insert_fixup(z)

def inorder(self, node):
if node != self.NIL:
self.inorder(node.left)
print(node.key, end=' ')
self.inorder(node.right)

AVL vs Red-Black: When to Use

FactorAVL TreeRed-Black Tree
StrictnessStricter balanceApproximate balance
Search performanceOptimalSlightly suboptimal
Insert/delete costHigher (more rotations)Lower (fewer rotations)
Typical useRead-heavy databasesGeneral-purpose maps

Key Takeaways

  • Red-Black trees use color attributes to maintain balance with O(logn)O(\log n) guarantees.
  • Five properties ensure the tree never becomes too unbalanced.
  • Insertions require at most 2 rotations; deletions require at most 3.
  • The relaxed balance constraints make Red-Black trees more efficient for frequent insertions/deletions.
  • They are the workhorse of associative containers in major language standard libraries.
Track Your Progress

Done with this topic? Mark it as complete to track your progress.

Was this page helpful?

💬

Discuss this page

Have a question or spot something confusing in "Red-Black Tree"? Ask below. Backed by GitHub Discussions—maintainers receive system notifications directly.