Counting sort
No comparisons: count how often each value occurs and compute each item's place in the output directly from prefix sums.
Comparison sorts cannot beat n log n. Counting sort does not compare at all: when the items are small integers in
0..k, it uses the value itself as an index.
- Time:
O(n + k) - Space:
O(n + k) - CLRS, section 8.2
Eight numbers from 0 to 5 with repeats; the count array has six cells.
def counting_sort(a):k = max(a)count = [0] * (k + 1)for x in a:count[x] = count[x] + 1for v in range(1, k + 1):count[v] = count[v] + count[v - 1]out = [0] * len(a)for j in range(len(a) - 1, -1, -1):count[a[j]] = count[a[j]] - 1out[count[a[j]]] = a[j]return out
Start
Local variables
Orange = changed in this step
a list
Call stack
- counting_sort()line 1
How the work grows with input size
Average of 12 random graphs per n (fixed seeds). Hollow marker = the input on screen.
- count
- prefix
- place
- current input (n=8)
Show as a table
| n | count | prefix | place |
|---|---|---|---|
| 4 | 4 | 7.4 | 4 |
| 6 | 6 | 8.3 | 6 |
| 8 | 8 | 8.2 | 8 |
| 10 | 10 | 8.3 | 10 |
| 12 | 12 | 8.8 | 12 |
| 14 | 14 | 8.8 | 14 |
| 16 | 16 | 8.8 | 16 |
Explanation
The idea
Comparison sorts cannot beat n log n. Counting sort does not compare at all: when the items are small integers in
0..k, it uses the value itself as an index.
- Count:
count[x]is how many timesxoccurs. - Prefix sums: after
count[v] += count[v − 1],count[v]is the number of items≤ v; so the last item with valuevbelongs at positioncount[v] − 1of the output. - Place: from the end of the array to the start, write each item to its place in the output and decrease its
count.
Cost
O(n + k) time and memory. When k is small compared with n, it beats every comparison sort; when k is large
(the "wide range" input), the count array drives the cost up.
Stability
Because the last phase starts from the end, the later of two equal items lands in the later position: the sort is stable. Radix sort needs exactly this property.
What to watch in the trace
- The
countandoutarrays are in the memory panel; the bars are the inputa, and thejarrow marks the item being placed. - Look at the counters: there is no
compareat all.