Why can quicksort's recursion depth reach O(n) while merge sort's is always O(log n)?
answer
- who decides where the split lands?
- one splits by index, the other by value
- trace the depth when a split is 1 and n-1
- the recursion tree collapses into a chain
- removing one element per level, not half
basics
~20 sMerge sort splits at the midpoint, so its recursion bottoms out after about log n levels. Quicksort splits wherever the pivot lands, and a worst split peels off one element per level, leaving n nested frames.
solid answer
~50 sRecursion depth is decided by the *split ratio*, and the two algorithms decide that ratio differently. Merge sort splits by index, so each child range is exactly half its parent no matter what the data contains — depth is ceil(log2 n), unconditionally. Quicksort splits by value: the boundary lands wherever the pivot's rank puts it. On a balanced split the depth is also about log n, but on a degenerate split of 1 and n-1 elements each level removes a single element, so the recursion becomes a chain of n frames — the same picture as a binary search tree that has degenerated into a linked list. Sorted or reverse-sorted input with a naively positioned pivot produces exactly that chain. The cost is real: recursion depth is stack space, so n frames on a large range can exhaust the stack before the quadratic comparison count even shows up.
code
pseudocode · 14 linesQUICKSORT(a, lo, hi):
if lo >= hi:
return
p = PARTITION(a, lo, hi) // ... p = final index of the pivot
QUICKSORT(a, lo, p - 1) // left child has p - lo elements
QUICKSORT(a, p + 1, hi) // right child has hi - p elements
MERGESORT(a, lo, hi):
if lo >= hi:
return
mid = (lo + hi) / 2 // ... mid is fixed by position, not by value
MERGESORT(a, lo, mid)
MERGESORT(a, mid + 1, hi)
MERGE(a, lo, mid, hi)go deeper
Recall that merge sort always cuts the range in half while quicksort cuts wherever the pivot happens to fall, and that a worst split leaves almost everything on one side.
Explain the mechanism: positional splits give a fixed ratio and logarithmic depth, value-based splits can remove one element per level, and a chain of frames is the result.
Show that you treat the stack as a real resource — quantify frames for a realistic input size and say which failure, the crash or the quadratic time, you would see first in production.
Own the distinction between a bound that holds by construction and one that holds in expectation, and be ready to say when a pipeline's requirements make that difference decisive.
### Depth is a property of the split ratio, not of the algorithm's name For any divide-and-conquer recursion, the depth is how many times you can shrink the problem before hitting the base case. If every level cuts the range to a fixed fraction — a half, a third, nine tenths — the depth is logarithmic in n, because repeated multiplication by a constant fraction reaches 1 in a logarithmic number of steps. If a level removes a *constant number of elements* instead of a constant fraction, the depth is linear. That single distinction, fraction versus fixed amount, is the whole answer. ### Merge sort: the split ratio is fixed by construction Merge sort divides by computing a midpoint index. The two children are of size ceil(n/2) and floor(n/2), and no value in the array can change that. So the depth of the recursion is ceil(log2 n) for every possible input. For half a million sensor readings — a year of one-per-minute samples is about 525,600 — that is 20 nested frames. There is no input, adversarial or otherwise, that makes it 21. ### Quicksort: the split ratio is data-dependent Quicksort's boundary lands at the pivot's rank within the range. Consider the same year of timestamps, but arriving in the order they were recorded — that is, already sorted — and a pivot taken from a fixed end of the range. The pivot is then the smallest or largest element present, so the partition produces one part of size 0 and one of size n-1: ``` range of 525600 -> 0 and 525599 range of 525599 -> 0 and 525598 ... ``` Each level strips exactly one element. The recursion tree is not a tree at all; it is a chain 525,600 frames deep. This is the same degeneration a binary search tree suffers when keys are inserted in sorted order: a structure that is logarithmic when balanced becomes linear when every split is maximally lopsided. ### The claim to get the direction right on "Quicksort's recursion depth is log n" is a statement about *balanced splits*, and it is what candidates say when they have memorised the average case. The precise statements are: - **Expected depth O(log n)** — over random inputs or a randomised pivot, lopsided splits are unlikely to stack up. - **Worst-case depth O(n)** — reached on inputs whose ordering interacts badly with how the pivot is chosen. - Merge sort's depth is **O(log n) worst case**, because there is no interaction to have. And note that a merely uneven split is harmless: a guaranteed 90/10 split still gives logarithmic depth, just with a bigger constant (log base 10/9 of n). Depth blows up only when the split is lopsided by a *fixed amount* rather than a fixed ratio, level after level. ### Recursion depth is space Each pending frame holds its arguments and its return address, so depth translates directly into stack memory. This is the part candidates skip: an algorithm's space complexity includes its recursion stack. Merge sort's stack is O(log n) frames; quicksort's is O(log n) expected and O(n) worst case. On a large input, the practical failure is not a slow sort — the process runs out of stack and dies. The quadratic comparison count of the same degenerate run would take far longer to become visible than the crash does. ### What this does not say Depth and time are separate claims. A degenerate quicksort has both problems (O(n) depth *and* O(n^2) comparisons), but they can be fixed independently, and the fix for one is not the fix for the other. Likewise, big-O here is an upper bound: labelling quicksort O(n) depth in the worst case does not mean typical runs are anywhere near it — on shuffled data the depth is a small multiple of log n with overwhelming probability. ### The interviewer's real target The question is a probe for whether you understand that quicksort's recursion *shape* is decided by the data while merge sort's is decided by arithmetic. Candidates who answer "both are log n because they both halve the input" have memorised the balanced case and never asked what guarantees the halving.
- Is quicksort's O(n) recursion depth a time problem, a space problem, or both?Both, but they are separate failures. The n nested frames are O(n) stack space — recursion depth counts toward space complexity — and on a large input that is what kills the process first. The same degenerate chain also does O(n^2) comparisons, because a level of size k costs k and the sizes run n, n-1, n-2 and so on. Fixing one does not fix the other.
- Which input shapes drive a naive quicksort into that degenerate chain?Any ordering that makes the pivot land at an extreme of its range, level after level. Already-sorted and reverse-sorted ranges do it when the pivot comes from a fixed end position, since the pivot is then the minimum or maximum present. A year of sensor timestamps appended in recording order is exactly that shape, which is why the failure shows up on real, well-behaved data rather than on adversarial input.
- Does a merely uneven split, say 90/10 at every level, also blow up the depth?No. A fixed ratio still shrinks the range geometrically, so the depth stays logarithmic — about log n taken to base 10/9, which is roughly 6.6 times log2 n. The constant is worse and the per-level cost is unchanged, but the recursion still bottoms out in logarithmic depth. Only a split that removes a fixed number of elements per level produces linear depth.
A balanced split builds a tree; a maximally lopsided split builds a ladder with one rung per element.
saying these in an interview costs you the question
- Says quicksort's recursion depth is always about log n
- Treats recursion depth as free because no heap allocation happens
- Claims merge sort can also degenerate on hostile input
- Confuses expected depth with worst-case depth
- Thinks any uneven split makes the depth linear