Skip to content
Back to skills

Algo Red Black Trees

ASecurity

Red-black tree — self-balancing BST with O(log n) operations, 5 invariants, insert fix-up with rotations and recoloring

  • 4 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added May 27, 2026
data-aipythongojavac++nodedatabase

Security analysis

A100/100

Scanned May 27, 2026

npx -y skills add Pavel-Kravchenko/Bioinformatics --skill algo-red-black-trees --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Algo Red Black Trees?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Algo Red Black Trees
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/pavel-kravchenko-algo-red-black-trees/badge)](https://www.skillsdirectory.com/skills/pavel-kravchenko-algo-red-black-trees)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: algo-red-black-trees
description: "Red-black tree — self-balancing BST with O(log n) operations, 5 invariants, insert fix-up with rotations and recoloring"
tool_type: python
primary_tool: Python
---

# Red-Black Trees

Self-balancing BST where each node is RED or BLACK. Guarantees O(log n) search/insert/delete.

## 5 Invariants

| # | Property |
|---|----------|
| 1 | Every node is RED or BLACK |
| 2 | Root is BLACK |
| 3 | Every leaf (NIL) is BLACK |
| 4 | RED node has only BLACK children (no red-red) |
| 5 | All root-to-leaf paths have equal BLACK node count (black-height) |

These guarantee: longest path <= 2x shortest path, so height is O(log n).

## Red-Black vs AVL

| Aspect | AVL | Red-Black |
|--------|-----|-----------|
| Height bound | 1.44 log n | 2 log n |
| Search | Faster (shorter) | Slightly slower |
| Insert/Delete | More rotations | Fewer rotations (recolor often suffices) |
| Best for | Read-heavy | Write-heavy |
| Used in | Database indexes | Java TreeMap, C++ std::map, Linux CFS |

## Implementation

```python
RED, BLACK = True, False

class RBNode:
    def __init__(self, data, color=RED):
        self.data = data
        self.color = color  # new nodes are RED
        self.parent = self.left = self.right = None

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

    def rotate_left(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 rotate_right(self, y):
        x = y.left
        y.left = x.right
        if x.right != self.NIL: x.right.parent = y
        x.parent = y.parent
        if y.parent is None: self.root = x
        elif y == y.parent.right: y.parent.right = x
        else: y.parent.left = x
        x.right = y; y.parent = x

    def insert(self, data):
        node = RBNode(data, color=RED)
        node.left = node.right = self.NIL
        parent = None
        current = self.root
        while current != self.NIL:
            parent = current
            if data < current.data: current = current.left
            elif data > current.data: current = current.right
            else: return  # no duplicates
        node.parent = parent
        if parent is None: self.root = node
        elif data < parent.data: parent.left = node
        else: parent.right = node
        self._fix_insert(node)

    def _fix_insert(self, node):
        while node != self.root and node.parent.color == RED:
            gp = node.parent.parent
            if node.parent == gp.left:
                uncle = gp.right
                if uncle.color == RED:  # Case 1: recolor
                    node.parent.color = uncle.color = BLACK
                    gp.color = RED; node = gp
                else:
                    if node == node.parent.right:  # Case 2: LR -> rotate left
                        node = node.parent; self.rotate_left(node)
                    node.parent.color = BLACK  # Case 3: LL -> rotate right
                    gp.color = RED; self.rotate_right(gp)
            else:  # mirror
                uncle = gp.left
                if uncle.color == RED:
                    node.parent.color = uncle.color = BLACK
                    gp.color = RED; node = gp
                else:
                    if node == node.parent.left:
                        node = node.parent; self.rotate_right(node)
                    node.parent.color = BLACK
                    gp.color = RED; self.rotate_left(gp)
        self.root.color = BLACK

    def search(self, data):
        current = self.root
        while current != self.NIL:
            if data == current.data: return current
            current = current.left if data < current.data else current.right
        return None
```

## Insert Fix-Up Cases (parent is left child of grandparent)

| Case | Condition | Action |
|---|---|---|
| 1 | Uncle is RED | Recolor parent+uncle BLACK, grandparent RED, move up |
| 2 | Uncle BLACK, node is right child | Left-rotate parent (reduces to case 3) |
| 3 | Uncle BLACK, node is left child | Right-rotate grandparent, recolor |

Mirror cases apply when parent is right child.

## Pitfalls

- NIL sentinel must be BLACK and shared — don't create new NIL nodes
- After insert fix-up, always force root to BLACK
- Deletion fix-up is significantly more complex (4 cases + mirrors) — omitted here but follows same rotation/recolor pattern

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…