Quickselect (k-th smallest)
Partition like quick sort, but continue only on the side that holds the k-th item; linear time on average.
To find the k-th smallest item (the median, say) we do not need to sort the whole array. Partition once as in quick
sort: the pivot lands in its final place, smaller items on its left and larger ones on its right. If the pivot's rank
is k, we are done; otherwise continue on one side only.
- Time:
O(n) on average, O(n²) at worst - Space:
O(1) - CLRS, section 9.2
The 4th smallest of eight numbers; only the needed side gets partitioned.
def quickselect(a, k):lo = 0hi = len(a) - 1while True:if lo == hi:return a[lo]p = partition(a, lo, hi)rank = p - lo + 1if k == rank:return a[p]if k < rank:hi = p - 1else:k = k - ranklo = p + 1def partition(a, lo, hi):pivot = a[hi]i = lo - 1for j in range(lo, hi):if a[j] <= pivot:i = i + 1a[i], a[j] = a[j], a[i]a[i + 1], a[hi] = a[hi], a[i + 1]return i + 1
Start
Local variables
Orange = changed in this step
a list
Call stack
- quickselect()line 1
How the work grows with input size
Average of 12 random graphs per n (fixed seeds). Hollow marker = the input on screen.
- comparisons
- current input (n=8)
Show as a table
| n | comparisons |
|---|---|
| 4 | 4.4 |
| 6 | 7.4 |
| 8 | 13.5 |
| 10 | 20 |
| 12 | 22.1 |
| 14 | 30.6 |
| 16 | 34.6 |
Explanation
The idea
To find the k-th smallest item (the median, say) we do not need to sort the whole array. Partition once as in quick
sort: the pivot lands in its final place, smaller items on its left and larger ones on its right. If the pivot's rank
is k, we are done; otherwise continue on one side only.
Cost
- On average each partition roughly halves the range:
n + n/2 + n/4 + … ≈ 2n, that isO(n), better than sorting (n log n). - In the worst case (the "sorted, the smallest" input) each partition removes only one item:
O(n²). CLRS builds a guaranteed pivot with the "median of medians" to make even the worst case linear.
What to watch in the trace
- The blue band is the range
lo..hithat holds the answer; watch it shrink after every partition. kis shown above the array and goes down when the search moves right.