๐Ÿ”ดโšซ Red-Black Tree

Self-balancing binary search tree with guaranteed O(log n) operations

Overview

Implements a persistent red-black tree โ€” a self-balancing BST that maintains balance invariants through node coloring. Guarantees O(log n) for insert, delete, and lookup. All operations return new trees (functional/immutable).

Concepts Demonstrated

Red-Black Invariants

  1. Every node is red or black
  2. The root is always black
  3. No red node has a red child
  4. Every path from root to leaf has the same number of black nodes

These invariants guarantee the tree height is at most 2ยทlogโ‚‚(n+1), ensuring logarithmic operations.

The Balance Function

(* Okasaki's elegant four-case balance *)
let balance = function
  | Black, Node(Red, Node(Red,a,x,b), y, c), z, d
  | Black, Node(Red, a, x, Node(Red,b,y,c)), z, d
  | Black, a, x, Node(Red, Node(Red,b,y,c), z, d)
  | Black, a, x, Node(Red, b, y, Node(Red,c,z,d))
    โ†’ Node(Red, Node(Black,a,x,b), y, Node(Black,c,z,d))
  | color, left, key, right
    โ†’ Node(color, left, key, right)

This single function handles all four rotation cases with pattern matching โ€” one of the most elegant examples of algebraic data types in action.

Key Functions

FunctionDescription
insertAdd a key-value pair, rebalancing as needed
findLook up a key (returns option)
removeDelete a key, maintaining balance
memCheck if a key exists
min_binding / max_bindingSmallest/largest key
fold / iterIn-order traversal
of_list / to_listConvert to/from sorted lists