Skip to content
Part IA Lent Term

Counting Sort

Overview

Counting sort sorts nn integers drawn from a known range [0,k][0, k]. It is not a comparison sort, so it evades the Ω(nlogn)\Omega(n \log n) lower bound. Instead, it counts occurrences of each value, computes cumulative counts to determine output positions, and places each element directly into its correct sorted position.

Running time is Θ(n+k)\Theta(n + k); space is Θ(n+k)\Theta(n + k). Counting sort is stable. It is practical linear time only when k=O(n)k = O(n).

Algorithm

Counting sort diagram

Given input array A of length nn and maximum value kk:

  1. Allocate a count array C[0..k], initialise all entries to 0.
  2. For each element vv in A, increment C[v].
  3. Convert C to cumulative counts: for i=1i = 1 to kk, set C[i] = C[i] + C[i-1]. Now C[i] is the number of elements i\le i.
  4. Allocate output array B[1..n]. Iterate through A from right to left (to preserve stability): for each v=A[j]v = A[j], place it at B[C[v]], then decrement C[v].

The right-to-left pass in step 4 is what guarantees stability: when duplicate values exist, the element appearing later in the input is placed later in the output.

Worked Example

Sort A = [2, 5, 3, 0, 2, 3, 0, 3] with k=5k = 5.

Step 1: Count occurrences

ii012345
C[i]202301

Step 2: Cumulative counts

ii012345
C[i]224778

Interpretation: there are 2 elements 0\le 0, 2 elements 1\le 1, 4 elements 2\le 2, etc. So the value 2 will occupy output positions 3 and 4 (1-indexed: C[2] = 4, then decrement yields 3 for next occurrence).

Step 3: Place elements (right to left)

  • A[8]=3A[8] = 3: C[3] = 7B[7] = 3, C[3] = 6
  • A[7]=0A[7] = 0: C[0] = 2B[2] = 0, C[0] = 1
  • A[6]=3A[6] = 3: C[3] = 6B[6] = 3, C[3] = 5
  • A[5]=2A[5] = 2: C[2] = 4B[4] = 2, C[2] = 3
  • A[4]=0A[4] = 0: C[0] = 1B[1] = 0, C[0] = 0
  • A[3]=3A[3] = 3: C[3] = 5B[5] = 3, C[3] = 4
  • A[2]=5A[2] = 5: C[5] = 8B[8] = 5, C[5] = 7
  • A[1]=2A[1] = 2: C[2] = 3B[3] = 2, C[2] = 2

Output: B = [0, 0, 2, 2, 3, 3, 3, 5]. Notice that the two 0s preserve their original relative order, as do the two 2s and three 3s. The sort is stable.

Complexity Analysis

StepCost
Initialise C[0..k]Θ(k)\Theta(k)
Count occurrencesΘ(n)\Theta(n)
Cumulative countsΘ(k)\Theta(k)
Place elementsΘ(n)\Theta(n)
TotalΘ(n+k)\Theta(n + k)

Space: Θ(n+k)\Theta(n + k) for the output array and count array. Counting sort is not in-place.

When Is It Linear?

If k=O(n)k = O(n), then Θ(n+k)=Θ(n)\Theta(n + k) = \Theta(n). This is the practical regime. If kk is much larger than nn (e.g. sorting a handful of 64-bit integers), then counting sort is Θ(k)\Theta(k)-dominated and wastes both time and space.

Why It Beats the Lower Bound

The Ω(nlogn)\Omega(n \log n) lower bound applies only to comparison-based sorting. Counting sort never compares elements against each other; it inspects the numerical value of each key directly and uses that value as an array index. This is not a valid operation in the comparison model.

Stability

Counting sort is stable because we iterate the input from right to left when placing elements. The last occurrence of a value in the original array is placed at the rightmost available position for that value in the output, preserving relative order amongst equal keys.

Summary

PropertyValue
TypeNon-comparison, integer sort
Worst-case timeΘ(n+k)\Theta(n + k)
SpaceΘ(n+k)\Theta(n + k)
StableYes
In-placeNo
Practical whenk=O(n)k = O(n)
Beats Ω(nlogn)\Omega(n \log n)Yes (not comparison-based)