Quicksort & PARTITION
◈ 5 cardsIn-place divide-and-conquer with a trivial combine; the four-region PARTITION invariant; best/avg Θ(n lg n) but worst Θ(n²) on sorted input.
All the work is in the divide
Quicksort is divide-and-conquer where partitioning is everything and the combine step does nothing. To sort : PARTITION picks a pivot, rearranges so everything pivot is on its left and everything pivot is on its right, and returns the pivot's final index . Then recurse on and . Because the pivot is already in its final sorted slot and each side is sorted in place, no merge is needed — that is why quicksort sorts in place.
PARTITION and its four-region invariant
Lomuto's PARTITION takes as the pivot and scans from to , maintaining four regions:
- — known (the low side),
- — known (the high side),
- — not yet examined,
- — the pivot, parked at the end.
When , increment and swap (grow the low side); otherwise just advance (grow the high side). After the loop, swap to drop the pivot between the two sides and return . The loop does work per element, so PARTITION is .
When it wins and when it loses
- Best case: every split is balanced (size each). .
- Worst case: every split is vs . .
- Average case: — and remarkably, any constant-ratio split (even 9-to-1) still gives , because the recursion tree stays deep with work per level.
The worst case is triggered by already-sorted (or reverse-sorted) input when the pivot is always : the pivot is always the max (or min), so one side is always empty. Sorted input — the easy case for insertion sort — is the worst case for fixed-pivot quicksort. The next lesson fixes this with randomization.
Worked example
PARTITION on with pivot returns index and leaves — everything left of index 3 is , everything right is , and sits in its final place. Running full quicksort then yields the sorted list. Both runnable exercises reproduce this.