Red-Black Trees

A Red-Black Tree is a self-balancing Binary Search Tree in which every node stores a color — either red or black. The tree enforces a set of coloring rules that together ensure the longest root-to-leaf path is at most twice the length of the shortest path. This keeps the tree balanced enough to guarantee O(log n) time for search, insertion, and deletion.

Red-Black trees are widely used in practice: Java's TreeMap and TreeSet, C++'s std::map and std::set, and the Linux kernel's Completely Fair Scheduler all use Red-Black trees internally.

Rendering diagram...

Red-Black Tree Properties#

A valid Red-Black tree must satisfy these five properties:

PropertyDescription
1. Node ColorEvery node is either RED or BLACK
2. Root PropertyThe root is always BLACK
3. Leaf PropertyAll leaves (NIL nodes) are BLACK
4. Red PropertyIf a node is RED, both its children must be BLACK (no two consecutive reds)
5. Black HeightEvery path from a node to its descendant NIL nodes has the same number of BLACK nodes

The black height of a node is the number of black nodes on any downward path from that node to a NIL leaf, not counting the node itself. Property 5 ensures balance: because every path from a node to its descendant NIL leaves contains the same number of black nodes, no path can grow disproportionately long relative to another. This is the structural guarantee that bounds the tree's height to O(log n).

Valid Red-Black Tree
Rendering diagram...
Invalid: Two Consecutive Reds
Rendering diagram...

Why Red-Black Trees?#

Both AVL trees and Red-Black trees are self-balancing BSTs, but they make different trade-offs. AVL trees enforce stricter balance, which makes lookups faster but requires more rotations after every insert or delete. Red-Black trees permit slightly more imbalance, reducing the number of structural fixes needed on writes. This makes Red-Black trees the preferred choice in most general-purpose standard libraries.

PropertyAVL TreeRed-Black Tree
Balance StrictnessHeight difference at most 1Longest path at most 2x the shortest
Height Bound1.44 log(n)2 log(n+1)
Lookup SpeedFaster (stricter balance)Slightly slower
Insert/DeleteMore rotations neededFewer rotations (at most 2-3)
Use CaseRead-heavy workloadsWrite-heavy workloads
Used InDatabases, search enginesLanguage libraries, OS kernels

Red-Black Tree Node

Node structure with color, parent pointer, and NIL leaves

Red-Black node with color and parent pointer

Rotations#

Like AVL trees, Red-Black trees use rotations to restructure the tree without violating the BST ordering property. A rotation repositions nodes locally — values are never moved, only the parent-child links change. Crucially, in-order traversal order is preserved before and after any rotation. The rotation mechanics are the same as in AVL trees.

Before Left Rotation
Rendering diagram...
After Left Rotation
Rendering diagram...

Rotations

Left and right rotations to restructure the tree

Time:O(1)Space:O(1)

Insertion#

Insertion proceeds in two phases:

  1. BST Insert: Place the new node using standard BST logic, coloring it RED. A red node is always inserted first because adding it does not change the black height of any path — it can only violate the Red Property (no two consecutive red nodes).
  2. Fix Violations: Walk up the tree and restore any Red Property violations using recoloring and rotations.

The key factor in each fixup step is the uncle's color — the sibling of the inserted node's parent:

  • Uncle is RED: Fix cheaply by recoloring. Push the "redness" up to the grandparent and continue checking from there.
  • Uncle is BLACK: A structural fix is needed. One or two rotations will resolve the violation without further propagation.
CaseConditionAction
Case 1Uncle is REDColor parent and uncle BLACK, grandparent RED; continue fixup from grandparent
Case 2Uncle is BLACK, node is inner childRotate parent to straighten the zigzag; falls into Case 3
Case 3Uncle is BLACK, node is outer childRotate grandparent and recolor; violation resolved

An outer child (Case 3) means the new node forms a straight line with its parent and grandparent — for example, a left child of a left child. An inner child (Case 2) forms a zigzag — the new node bends in the opposite direction from its parent, for example, a right child of a left child. Case 2 first straightens the zigzag with a rotation, which converts the shape into a Case 3 configuration that is then resolved with one more rotation.

Case 1: Uncle is RED
Rendering diagram...
After Recolor
Rendering diagram...
Case 3: Uncle BLACK, Outer Child
Rendering diagram...
After Right Rotate G + Recolor
Rendering diagram...

Red-Black Insert

Insert a node and fix any Red-Black property violations

Time:O(log n)Space:O(1)Best:O(log n)Worst:O(log n)

Deletion#

Deletion is the most complex operation in a Red-Black tree. When we remove a RED node, all path black-heights remain unchanged — no fixup is needed. But when we remove a BLACK node, the black height of every path that passed through it decreases by one, creating an imbalance.

The algorithm handles this by conceptually assigning a double-black state to the node that takes the deleted node's place. This represents the "missing" black that must be redistributed or absorbed. The fixup loop eliminates the double-black condition by examining the node's sibling and the sibling's children (called nephews) to determine the appropriate action.

CaseConditionAction
Case 1Sibling is REDRotate parent and recolor to expose a BLACK sibling; re-examine as Case 2, 3, or 4
Case 2Sibling BLACK, both nephews BLACKRecolor sibling RED and move the double-black up to the parent
Case 3Sibling BLACK, inner nephew RED (outer BLACK)Rotate sibling and recolor to convert into Case 4
Case 4Sibling BLACK, outer nephew REDRotate parent, transfer colors appropriately; double-black eliminated

Red-Black Delete

Delete a node and fix any Red-Black property violations

Time:O(log n)Space:O(1)Best:O(log n)Worst:O(log n)

Complete Implementation#

Complete Red-Black Tree

Full implementation with insert, delete, and search

Complete Red-Black tree with all operations

Applications#

Red-Black trees are the data structure of choice wherever you need ordered data with fast, predictable insert and delete performance. Their O(log n) worst-case guarantee and low rotation count make them practical for systems that must handle many writes, not just reads.

ApplicationWhy Red-Black Tree?
Java TreeMap/TreeSetGuaranteed O(log n) for all operations with fewer rotations than AVL on writes
C++ std::map/std::setOrdered containers in the C++ standard library
Linux CFS SchedulerThe Completely Fair Scheduler uses an RB tree to order runnable tasks by virtual runtime
Nginx Timer EventsEfficient scheduling of timed events in the web server
Memory AllocatorsTracking free memory blocks by size for fast allocation
Database IndexesSome databases use RB trees for in-memory index structures

Reviewing AI-Generated Code#

Red-Black trees are complex enough that AI-generated implementations often contain subtle bugs — an incorrect case branch, a missing parent-pointer update, or a forgotten root recolor. These mistakes can produce a tree that passes basic tests but silently violates one of the five properties, leading to correctness issues only discovered much later. Knowing what to look for helps you verify AI-generated code quickly.

IssueWhat to CheckCommon AI Mistake
Root colorRoot must always be BLACK after operationsForgetting to color root BLACK
NIL handlingNIL sentinel is always BLACKUsing null instead of NIL sentinel
Case selectionUncle color determines the caseWrong case for uncle's color
Parent pointersMust update parent pointers during rotationLeaving stale parent pointers
Consecutive redsTwo RED nodes cannot be adjacentMissing fixup after insert

Spotting AI Red-Black Bugs

Common errors in AI-generated Red-Black tree code

Correct fixup that ensures root is always BLACK

Questions to Ask AI About Red-Black Code#

Use these targeted questions to probe AI-generated implementations:

  1. "What color is the root after insertion?" — Must always be BLACK. Case 1 recolors the grandparent RED; if that grandparent was the root, the final root.color = BLACK line is essential.
  2. "Is there a NIL sentinel node?" — A sentinel simplifies boundary checks throughout the code. Implementations that use null directly are error-prone and harder to follow.
  3. "Show the tree after inserting these values." — Step through a short example and verify all five properties hold at each stage.
  4. "How many rotations at most?" — Insertion requires at most 2 rotations; deletion requires at most 3. More than that signals a logic error.

Summary#

The five properties work together as a system: the root and NIL rules anchor the coloring, the Red Property limits how many red nodes can appear consecutively, and the Black-Height Property ensures all paths stay within a factor of two of each other in length. Violating any one property can break the O(log n) guarantee.

ConceptKey Point
Color PropertyEvery node is RED or BLACK
Root PropertyRoot is always BLACK
Red PropertyRED nodes cannot have RED children
Black HeightAll paths from node to NIL have same BLACK count
InsertAdd RED node, fix with at most 2 rotations
DeleteComplex fixup, at most 3 rotations
HeightAt most 2·log(n+1), less strict than AVL's 1.44·log(n)
Use CaseWrite-heavy workloads, language standard libraries

Red-Black trees offer a strong trade-off between structural balance and modification efficiency. They allow slightly more height than AVL trees in exchange for fewer rotations on insert and delete — a worthwhile trade-off for write-heavy workloads and general-purpose containers. For disk-based or block-oriented storage where minimizing I/O operations matters more than rotation count, consider B-Trees, which achieve high branching factors and are optimized for block I/O.