Binary Search Tree Fundamentals
A binary search tree (BST) is a binary tree with an ordering invariant: for every node, all values in its left subtree are smaller and all values in its right subtree are larger. This property enables O(log n) search, insert, and delete when the tree is balanced. BSTs power Java’s TreeMap/TreeSet, C++’s std::set, and underpin database indexes.
What is BST?
A BST enforces one simple rule: left < node < right. For every node, every value in its left subtree is strictly less, and every value in its right subtree is strictly greater. This invariant turns the tree into a sorted structure — an inorder traversal yields elements in sorted order, and searching is like binary search: at each node, go left if the target is smaller, right if larger, eliminating half the remaining tree each step.
The critical issue: a BST is only efficient when balanced.
Height ≈ log n
AVL trees and Red-Black trees automatically rebalance after every insert/delete via rotations, keeping the height at O(log n) and guaranteeing O(log n) for all operations.
- AVL: strict balance (height diff ≤ 1)
- Red-Black: relaxed balance (faster inserts)
- Java
TreeMap= Red-Black tree
Height ≈ n (worst case)
If you insert sorted data into a plain BST, it degenerates into a linked list. Every operation becomes O(n). This is why self-balancing variants exist.
- Insert [1,2,3,4,5] → a right-skewed chain
- Search becomes linear scan
- Never use a plain BST in production
Core Operations
node.left = insert(node.left, val). The same pattern is used by delete — learn it once, apply everywhere.node.left.val < node.val. This misses cases where a deep-left node violates an ancestor’s constraint. The correct approach passes min and max bounds down the tree. Alternatively, do an inorder traversal and check that the sequence is strictly increasing.Diagrams & Operations
Java Quick Reference
Java’s TreeMap and TreeSet are self-balancing BSTs (Red-Black trees). For interviews, you’ll also need the manual recursive search/insert/delete.
Time & Space Complexity
| Operation | Balanced (AVL/RB) | Unbalanced (worst) | Space |
|---|---|---|---|
| Search | O(log n) | O(n) | O(h) recursive / O(1) iterative |
| Insert | O(log n) | O(n) | O(h) recursive |
| Delete | O(log n) | O(n) | O(h) recursive |
| Inorder traversal | O(n) | O(n) | O(h) stack |
| Find min / max | O(log n) | O(n) | O(1) iterative |
A BST of n nodes uses O(n) space for the nodes. Recursive operations use O(h) call-stack space. For balanced trees h = O(log n); for skewed trees h = O(n). Iterative search uses O(1) auxiliary space. Self-balancing trees add a small constant per node (colour bit for Red-Black, balance factor for AVL) but this doesn’t change the asymptotic space.
When to Use BST
Use This When
- You need sorted-order operations — find the kth smallest, iterate in sorted order, find the predecessor/successor of a value.
- Range queries — “all keys between 10 and 50”, floor/ceiling lookups. TreeMap’s
subMap,floorKey,ceilingKeyrely on BST structure. - Dynamic sorted data — when elements are frequently inserted/deleted and you still need sorted access. Arrays need O(n) shifts; BSTs do it in O(log n).
Avoid When
- You only need key existence / lookup — HashMap is O(1) average vs. BST’s O(log n). If you don’t need ordering, a hash map is always faster.
- Data is static and sorted — binary search on a sorted array gives O(log n) search with better cache performance and no pointer overhead.
| Structure | Search | Insert | Ordered? | Best For |
|---|---|---|---|---|
| BST (balanced) ← this one | O(log n) | O(log n) | Yes | Sorted data, range queries, kth element |
| HashMap | O(1) avg | O(1) avg | No | Pure lookup, frequency counting |
| Sorted Array | O(log n) | O(n) shift | Yes | Static data, binary search |
LeetCode Problems
BST interview problems test two things: exploiting the sorted invariant (validate BST, kth smallest, inorder successor) and structural mutations (insert, delete, convert sorted array to BST). The key insight is always the same: inorder traversal = sorted order, and you can prune half the tree at each step.
- Easy Search in a BST — Go left if target < node, right if target > node, return when equal — O(h) recursive or iterative.
- Medium Validate Binary Search Tree — Pass min/max bounds down recursively, or do an inorder traversal and check strictly increasing.
- Medium Kth Smallest Element in a BST — Inorder traversal stopping at the kth node — O(h + k). Iterative stack version is cleaner.
- Medium Delete Node in a BST — Find the node, handle three cases: leaf, one child, two children (swap with inorder successor).
- Hard Recover Binary Search Tree — Two nodes are swapped. Do an inorder traversal; find two violations in the sorted sequence and swap them back.