CountingSort — when does it apply and what is its complex… — Cracked Java
// Data Structures & Algorithms · Sorting Algorithms
MidTheory

CountingSort — when does it apply and what is its complexity?

Problem. What is CountingSort, when does it apply, and what's its complexity?

The idea

CountingSort is a non-comparison sort. Instead of comparing elements, it counts how many times each key value occurs, then uses a running prefix sum to place each element directly at its final index. It applies only when keys are integers in a small, known range [0, k).

int[] countingSort(int[] a, int k) {        // values in [0, k)
    int[] count = new int[k];
    for (int x : a) count[x]++;              // tally occurrences
    for (int i = 1; i < k; i++)
        count[i] += count[i - 1];            // prefix sums -> end positions
    int[] out = new int[a.length];
    for (int i = a.length - 1; i >= 0; i--)  // iterate right-to-left for STABILITY
        out[--count[a[i]]] = a[i];
    return out;
}

Complexity

  • Time: O(n + k) — one pass to count, one over the buckets, one to place.
  • Space: O(n + k) — the count array plus the output buffer.

When k = O(n) this is linear — beating the Ω(n log n) comparison-sort lower bound, because it never compares; it indexes. When k ≫ n (e.g., sorting 10 values in range [0, 10⁹)) the count array dwarfs the data and it becomes wasteful — that's the boundary where you fall back to a comparison sort or to RadixSort (which applies CountingSort digit-by-digit to handle large ranges).

Stability matters

Iterating the input right-to-left while decrementing the prefix-sum positions keeps equal keys in original order — making CountingSort stable. That stability is exactly what makes it usable as the inner pass of RadixSort.

Mark your status