1. Home
  2. Data Structures
  3. Red-Black Tree

Red-Black Tree

A self-balancing BST that colours every node red or black. Insertions fix themselves with a recolouring or at most two rotations.

Interactive 3DAdvanced14 min readDSAUpdated

Drag to rotate · Right-drag to pan · Click, then scroll to zoom · Space play · ←→ step

What's happening

Pseudocode

    Try this in the 3D model

    • Insert 12. The uncle is red. Which three nodes change colour, and why doesn't any node move?
    • Now insert 13. Watch case 2 straighten the zig-zag, then case 3 rotate. Which node ends on top?
    • Press Insert 10…100 in order. What height does the tree reach compared with a plain BST?
    • After any insert, pick a node and count the black nodes on every path down from it. Are the counts equal?

    The idea

    A plain binary search tree can degrade into a long chain, for example when keys arrive in sorted order, and then every operation becomes O(n). Self-balancing trees prevent that. An AVL tree tracks heights exactly. A red-black tree uses a cheaper trick: one extra bit per node, its colour, and a few rules that keep the tree roughly balanced.

    The five rules

    1. Every node is red or black.
    2. The root is black.
    3. Every empty child (NIL leaf) counts as black.
    4. A red node never has a red child (no two reds in a row).
    5. From any node, every path down to its NIL leaves passes the same number of black nodes (its black-height).

    Rules 4 and 5 together guarantee that the longest path (alternating red and black) is at most twice the shortest (all black). So the height is at most 2 · log₂(n + 1).

    Inserting

    1. Insert the key like a normal BST and colour it red. A red node doesn’t change any black count, so rule 5 still holds.
    2. If its parent is black, you are done.
    3. If its parent is red, rule 4 is broken. Look at the uncle (the parent’s sibling):
    Case Situation Fix
    1 Uncle is red Recolour: parent and uncle become black, grandparent becomes red. Move z up to the grandparent and repeat.
    2 Uncle is black, z is an inner child (zig-zag) Rotate at the parent to make a straight line. That turns it into case 3.
    3 Uncle is black, z is an outer child (straight line) Colour the parent black and the grandparent red, then rotate at the grandparent. Done.

    Finally, colour the root black.

    Case 1 only recolours, though it can repeat up the tree. Cases 2 and 3 end the fix-up with at most two rotations in total.

    Example

    Start with 20 (black), whose children 10 and 30 are black, and 10 has red children 5 and 15.

    • Insert 12: it goes under 15 as a red child. Its parent 15 is red and its uncle 5 is red, so this is case 1: 15 and 5 turn black and 10 turns red. 10’s parent (20) is black, so we stop.
    • Insert 13: it goes under 12 as a right child. Parent 12 is red and the uncle (15’s right side) is NIL, so black. 13 is an inner child, so case 2 rotates left at 12. That gives a straight line, and case 3 colours 13 black and 15 red, then rotates right at 15. Now 13 has children 12 and 15, both red.

    Code (insertion fix-up)

    RED, BLACK = True, False
    
    class Node:
        def __init__(self, key):
            self.key, self.color = key, RED
            self.left = self.right = self.parent = None
    
    def is_red(n):
        return n is not None and n.color == RED
    
    def fix_insert(tree, z):
        while is_red(z.parent):
            p, g = z.parent, z.parent.parent
            if p is g.left:
                uncle = g.right
                if is_red(uncle):                       # case 1: recolour
                    p.color = uncle.color = BLACK
                    g.color = RED
                    z = g
                    continue
                if z is p.right:                        # case 2: inner child
                    z = p
                    tree.rotate_left(z)
                    p = z.parent
                p.color, g.color = BLACK, RED           # case 3: outer child
                tree.rotate_right(g)
            else:                                       # mirror image
                uncle = g.left
                if is_red(uncle):
                    p.color = uncle.color = BLACK
                    g.color = RED
                    z = g
                    continue
                if z is p.left:
                    z = p
                    tree.rotate_right(z)
                    p = z.parent
                p.color, g.color = BLACK, RED
                tree.rotate_left(g)
        tree.root.color = BLACK

    rotate_left and rotate_right are the same rotations used by AVL trees. They move nodes but keep the BST order.

    Red-black tree vs AVL tree

    Red-black tree AVL tree
    Balance rule Colours, black-heights Height difference ≤ 1
    Maximum height 2 log₂(n + 1) ≈ 1.44 log₂ n
    Rotations per insert at most 2 at most 2
    Rotations per delete at most 3 up to O(log n)
    Best for Many inserts and deletes Many lookups

    Where is it used?

    Red-black trees are everywhere: Java’s TreeMap and TreeSet, C++’s std::map and std::set, the Linux kernel (its CPU scheduler, CFS, keeps runnable tasks in a red-black tree) and many database and file-system indexes.

    Common mistakes

    • Inserting the new node as black. That breaks rule 5 everywhere along its path.
    • Forgetting that a missing child (NIL) is black. A missing uncle means case 2 or 3, not case 1.
    • Applying case 3 to a zig-zag shape. Do the case 2 rotation first.
    • Forgetting the last step: colour the root black.

    Complexity at a glance

    Case / operationTimeWhy
    SearchO(log n)Height is at most 2 · log₂(n + 1).
    InsertO(log n)Recolourings go up the tree; at most 2 rotations.
    DeleteO(log n)At most 3 rotations.
    Extra spaceO(n)

    Quick check

    Test yourself — pick an answer to see if you got it.

    1. What colour is a newly inserted node, and why?

    2. The new node's parent and uncle are both red. What does the fix-up do?

    3. What is the maximum height of a red-black tree with n nodes?

    4. Compared with an AVL tree, a red-black tree…

    Saved only in this browser — no account needed.
    Spotted a mistake or a bug in the 3D model?

    Report a mistake

    in Red-Black Tree. Thank you — every report makes the lesson better for the next reader.

    We'll also include a link to the step of the 3D model you're on and your browser type, so we can reproduce it.