Inorder Successor in a BST asks for the next node in sorted order. It is a clean exercise in using the BST ordering property instead of actually doing a traversal — the whole answer comes from comparisons on the way down.
Problem. Given the root of a binary search tree and a node p in it, return the node with the
smallest value that is larger than p.val — its inorder successor. Return None if no such node
exists.
Example: in the BST with inorder order 4, 8, 10, 12, 14, 20, 22, the successor of 14 is 20.
The slow way first
The obvious idea: do a full inorder traversal of the tree, collect the values in sorted order, find p in that list, and return the next one. That works, but it visits every node — O(n) time and O(n) space for the list — even though the tree already knows its own order.
The question to ask: can I use the BST property to avoid touching the whole tree? In a BST, everything in the left subtree is smaller and everything in the right is larger. That ordering is exactly what "successor" is about, so we should be able to navigate to the answer directly.
The idea: right subtree, or last left turn
There are two cases.
phas a right subtree. Then the successor is the smallest value bigger thanp— which is the leftmost node of that right subtree. Step into the right child, then go left as far as you can.phas no right subtree. Then the successor must be an ancestor. Walk down from the root towardp. Every time you turn left, that node is bigger thanpand is a candidate. The last such left-turn ancestor is the answer. If you never turned left, there is no successor.
The animation walks through case 2, the trickier one: a roving cur pointer descends from the root, and we remember each node where p belongs in its left subtree.
Walk through it
Step through the animation. We want the successor of 14, which has no right child. The pointer cur starts at the root 20: since 14 < 20, we record 20 and turn left. At 8 and at 12, 14 is larger, so we turn right and keep 20 as the candidate. We arrive at 14 itself with nothing to its right, so the walk ends — and the last left turn, 20, is the answer.
Pseudocode
# Case 1: p has a right subtree
if p has a right child:
node = p.right
walk left while node.left exists
return node
# Case 2: no right subtree -> look at ancestors
succ = None
cur = root
while cur is not None:
if p.val < cur.val:
succ = cur # turning left: cur is a candidate
cur = cur.left
else:
cur = cur.right # turning right: candidate unchanged
return succThe Python solution
def inorder_successor(root, p):
# Case 1: right subtree exists -> leftmost of it
if p.right:
node = p.right
while node.left:
node = node.left
return node
# Case 2: track the last left-turn ancestor
succ = None
cur = root
while cur:
if p.val < cur.val:
succ = cur
cur = cur.left
else:
cur = cur.right
return succ- Lines 3-7 handle case 1: if
p.rightexists, step into it and slide left until there is noleftchild — that leftmost node is the smallest value bigger thanp. succstarts asNone, so if we never turn left we correctly returnNone.- The
while curloop descends the tree comparingp.valto each node. - Line 12 is the heart of it: when
p.val < cur.val,plives incur's left subtree, socuris a better (smaller) candidate than any we had — record it and go left. - Otherwise
pis to the right, socuris too small to be the successor; go right and keep the old candidate.
Complexity
| Case | Time | Notes |
|---|---|---|
| Full inorder traversal | O(n) (moderate) | visits every node, builds a list |
| BST navigation (this solution) | O(h) (moderate) | one path down, h = tree height |
O(1) (fast)We follow a single root-to-leaf path, so the work is the tree height h — O(log n) for a balanced BST, O(n) in the worst case for a skewed one. No extra list is needed, so space is O(1).
When this pattern shows up
Whenever a problem hands you a BST and asks about order — successor, predecessor, kth smallest,
range queries — resist doing a full traversal. The left-smaller / right-larger property lets you steer
directly to the answer along one path in O(h).
Do not forget case 1. If p has a right child, the successor is inside that subtree, not an ancestor.
A solution that only walks down from the root and tracks left turns gives the wrong answer when p.right
exists.
Practice
Suppose we instead ask for the successor of 12 in the same tree. 12 has a right child (14). Which case applies and what is the answer?
1. When p has a right subtree, where is its inorder successor?
2. When p has no right subtree, which ancestor is the successor?
3. Why is the time O(h) and not O(n)?
4. What does succ being None at the end mean?