Sort integers by counting occurrences of each key and reconstructing the output in linear time.
Counting sort is a non-comparison sorting algorithm for integer keys within a bounded range. It counts how many times each value appears, then reconstructs the sorted order using these counts.
It runs in linear time when the key range is not significantly larger than the number of elements.
Problem
Given an array of integers where each value lies in a range , produce a sorted array.
Idea
Instead of comparing elements, count how many times each value appears.
Let:
- be the number of elements equal to
- Then expand counts to reconstruct the sorted sequence
For stable sorting, use prefix sums to compute positions.
Algorithm (basic version)
counting_sort(A, k):
C = array of size k+1 filled with 0
for x in A:
C[x] += 1
i = 0
for v from 0 to k:
while C[v] > 0:
A[i] = v
i += 1
C[v] -= 1Stable Version
To preserve order of equal elements:
- Count frequencies
- Compute prefix sums
- place elements into output array in reverse order
counting_sort_stable(A, k):
C = [0] * (k + 1)
for x in A:
C[x] += 1
for i in range(1, k + 1):
C[i] += C[i - 1]
B = [0] * len(A)
for i in range(len(A) - 1, -1, -1):
x = A[i]
C[x] -= 1
B[C[x]] = x
return BExample
Let:
Counts:
| value | count |
|---|---|
| 1 | 1 |
| 2 | 2 |
| 3 | 2 |
| 4 | 1 |
| 8 | 1 |
Reconstructed sorted array:
Correctness
Each element contributes exactly one count to its key bucket. The reconstruction step outputs exactly that many copies of each key in increasing order, so the result is sorted.
In the stable version, prefix sums map each occurrence to a unique final index, preserving relative order.
Complexity
| component | cost |
|---|---|
| counting | |
| prefix sum | |
| reconstruction | |
| total |
Space:
Constraints
Counting sort is efficient when:
If , memory and time become inefficient.
When to Use
Use counting sort when:
- keys are integers in a small range
- stability is required
- linear time is needed
- comparison sorting overhead is too high
It is often used as a building block in radix sort.
Implementation (Go)
func CountingSort(a []int, k int) []int {
count := make([]int, k+1)
for _, v := range a {
count[v]++
}
result := make([]int, len(a))
idx := 0
for v := 0; v <= k; v++ {
for count[v] > 0 {
result[idx] = v
idx++
count[v]--
}
}
return result
}