Overview
A balanced search tree is a BST that automatically keeps its height at O(log n) after every insert and delete, so operations never degrade to O(n). The main families are AVL trees (strict balance: subtree heights differ by at most 1), red-black trees (looser color rules, fewer rotations), and B-trees (many keys per node, used on disk).
Balance is restored with rotations: small local restructurings that change the shape of the tree while preserving the BST ordering. You rarely implement one in interviews, but you are expected to know why they exist, how rotations work, and which library types use them.
A hanging mobile tilts when you add weight to one side. You fix it by moving a pivot point, not by rebuilding the mobile. A rotation is that small pivot adjustment that restores balance while keeping everything in order.
When to use it
- You need guaranteed O(log n) ordered operations, even on adversarial or sorted input.
- Ordered maps and sets with floor, ceiling, and range iteration (TreeMap, TreeSet).
- Sliding window problems that need ordered access (median, closest value) in O(log n).
- On-disk indexes where each node read is expensive (B-trees and B+ trees).
Problem patterns it solves
Recognize it when: need floor / ceiling / min / max of the current window.
- 220. Contains Duplicate III
- 480. Sliding Window Median
- 1438. Longest Continuous Subarray With Absolute Diff <= Limit
Recognize it when: check the nearest existing booking before and after a new one.
- 729. My Calendar I
- 731. My Calendar II
- 352. Data Stream as Disjoint Intervals
Recognize it when: count of smaller elements, kth element in a dynamic set.
- 315. Count of Smaller Numbers After Self
- 2426. Number of Pairs Satisfying Inequality
Recognize it when: closest greater or smaller value seen so far.
- 456. 132 Pattern (TreeSet variant)
- 1818. Minimum Absolute Sum Difference
Where it is used in real software
Java TreeMap and TreeSet, and C++ std::map and std::set are red-black trees.
PostgreSQL, MySQL InnoDB, and SQLite indexes are B+ trees; file systems such as NTFS, Btrfs, and ext4 directory indexes use B-tree variants.
Red-black trees manage virtual memory areas, the CFS scheduler run queue, and timers.
Redis sorted sets use skip lists, a probabilistic alternative that gives the same O(log n) guarantees as balanced trees.
Key terms
- Balance factor (AVL)
- height(left) - height(right); must be -1, 0, or 1.
- Rotation
- A local restructuring (left or right) that preserves inorder order.
- Red-black rules
- Root is black, no two reds in a row, every root-to-null path has the same number of black nodes.
- B-tree order
- Maximum children per node; high order means a shallow tree with few disk reads.
- Skip list
- Linked lists with express lanes; randomized alternative to balanced trees.
AVL insertion
- 1Insert like a normal BST
Walk down and attach the new leaf.
- 2Update heights on the way up
height = 1 + max(left.height, right.height).
- 3Check the balance factor
If it becomes 2 or -2, the node is unbalanced.
- 4Left-Left or Right-Right case
A single rotation (right or left) fixes it.
- 5Left-Right or Right-Left case
Rotate the child first, then the node (double rotation).
Inserting 10, 20, 30 into an AVL tree
A plain BST would become a chain: 10 -> 20 -> 30
| Insert | Shape before fix | Balance factor | Fix | Result |
|---|---|---|---|---|
| 10 | 10 | 0 | none | root 10 |
| 20 | 10 -> right 20 | -1 at 10 | none | 10 with right child 20 |
| 30 | 10 -> 20 -> 30 (right chain) | -2 at 10 | left rotation at 10 | 20 with children 10 and 30 |
NOWInsert: 10 | Shape before fix: 10 | Balance factor: 0 | Fix: none | Result: root 10
One rotation turned a height-3 chain into a height-2 balanced tree. After n insertions, AVL height stays below about 1.44 log2(n).
Implementation
class AVLNode { constructor(val) { this.val = val; this.left = null; this.right = null; this.height = 1; }} const height = (n) => (n ? n.height : 0);const update = (n) => { n.height = 1 + Math.max(height(n.left), height(n.right)); };const balance = (n) => height(n.left) - height(n.right); function rotateRight(y) { const x = y.left; y.left = x.right; x.right = y; update(y); update(x); return x;} function rotateLeft(x) { const y = x.right; x.right = y.left; y.left = x; update(x); update(y); return y;} function insert(node, val) { if (!node) return new AVLNode(val); if (val < node.val) node.left = insert(node.left, val); else if (val > node.val) node.right = insert(node.right, val); else return node; update(node); const b = balance(node); if (b > 1 && val < node.left.val) return rotateRight(node); // Left-Left if (b < -1 && val > node.right.val) return rotateLeft(node); // Right-Right if (b > 1) { node.left = rotateLeft(node.left); return rotateRight(node); } // Left-Right if (b < -1) { node.right = rotateRight(node.right); return rotateLeft(node); } // Right-Left return node;}Complexity and performance
Guaranteed, worst case.
Constant pointer changes.
Stricter balance, faster lookups.
Fewer rotations on updates.
Trade-offs
AVL trees are more tightly balanced and faster for lookups; red-black trees need fewer rotations and are faster for frequent inserts and deletes, which is why libraries prefer them.
A B-tree node holds hundreds of keys that fit one disk page, so a billion keys need only 3 to 4 page reads.
Choose the tree only when you need order; otherwise a hash map's O(1) wins.
Variants and related techniques
BST by key and heap by random priority; balanced in expectation and simple to implement.
Moves accessed nodes to the root; amortized O(log n), great for skewed access.
Stores subtree sizes to answer rank and kth queries in O(log n).
Common mistakes
- Implementing a balanced tree in an interview when a library exists.
Fix: Use TreeMap / TreeSet in Java; in JavaScript, explain the structure and use a sorted array with binary search for small inputs.
- Forgetting to update heights after rotation.
Fix: Update the lower node first, then the new root.
- Integer overflow in range checks.
Fix: Use long values when computing x - diff and x + diff.
Interview questions
Why do we need balanced BSTs?
A plain BST can degenerate into a linked list on sorted input, making every operation O(n). Balancing guarantees O(log n) height.
What does a rotation do?
It moves a child up and its parent down on one side, redistributing height while preserving the left < node < right ordering.
Why do databases use B+ trees rather than red-black trees?
Disk and SSD reads happen in pages. B+ trees pack many keys per node to minimize page reads, and linked leaves make range scans efficient.
Practice problems
| Problem | Difficulty | What it trains |
|---|---|---|
| 729. My Calendar I | Medium | TreeMap floor and ceiling. |
| 220. Contains Duplicate III | Hard | Ordered sliding window. |
| 352. Data Stream as Disjoint Intervals | Hard | Merging with TreeMap. |
| 480. Sliding Window Median | Hard | Two ordered sets or two heaps. |
| Implement an AVL tree | Hard | Four rotation cases. |