Menu
Coddy logo textTech

Counting Sort

Last updated

Counting sort is a non-comparison sort for integers in a known, limited range. It counts how many times each value appears, then uses those counts to write every value directly into its sorted position - no comparisons needed. Press play above to watch the values get tallied and then placed back in order.

Counting sort runs in O(n + k) time, where k is the range of the input values. When k is not much larger than n it is extremely fast and can beat O(n log n) comparison sorts, but if the value range is huge the O(k) count array makes it impractical.

Time & space complexity

CaseComplexityNotes
TimeO(n + k)n elements, k = value range
SpaceO(n + k)Count array + output array
StableYesWhen placed right-to-left using prefix sums
Comparison?NoSorts by counting, not comparing
Best forSmall integer rangek close to n

Step by step

StepWhat happens
1Find the maximum value to size the count array.
2Count how many times each value occurs.
3(Optional) Convert counts to prefix sums for stability.
4Write each value into the output the number of times it appears.
5The output array is now fully sorted.

Worked example

Sorting [1, 4, 1, 2, 4] (values range from 0 to 4, so the count array has 5 slots):

PassStateAction
Scan inputcount = [0, 2, 1, 0, 2]Tally occurrences: 1 appears twice, 2 once, 4 twice.
Prefix sumscount = [0, 2, 3, 3, 5]Each slot now holds how many values are <= its index, giving final positions.
Place 4output = [_, _, _, _, 4]Read right-to-left: count[4] = 5, so 4 goes to index 4; decrement to 4.
Place 2output = [_, _, 2, _, 4]count[2] = 3, so 2 goes to index 2; decrement to 2.
Place 1output = [_, 1, 2, _, 4]count[1] = 2, so 1 goes to index 1; decrement to 1.
Place 4output = [_, 1, 2, 4, 4]count[4] = 4, so this 4 goes to index 3; decrement to 3.
Place 1output = [1, 1, 2, 4, 4]count[1] = 1, so this 1 goes to index 0. Array is sorted.

When to use counting sort

Use it whenAvoid it when
You sort integers (or keys mappable to integers) in a small, known range.The value range k is far larger than the element count n.
You need linear O(n + k) time and can afford the extra arrays.Memory is tight - the count array costs O(k) regardless of n.
You need a stable sort as a subroutine (e.g. inside radix sort).Keys are floats, strings, or arbitrary objects with no integer mapping.
The maximum value is bounded and cheap to compute up front.The range is unknown or unbounded, so you cannot size the count array.

Counting Sort code

A clean, runnable Counting Sort implementation in Python, JavaScript, Java, C++, C. Pick a language, copy the code, or open it pre-loaded in the Coddy Playground.

Counting Sort code in Python

Python
1def counting_sort(a):2    # Works for non-negative integers with a small max value3    counts = [0] * (max(a) + 1)4    for value in a:5        counts[value] += 16    # Prefix sums turn counts into final positions7    for i in range(1, len(counts)):8        counts[i] += counts[i - 1]9    out = [0] * len(a)10    for value in reversed(a):  # reversed keeps equal values stable11        counts[value] -= 112        out[counts[value]] = value13    return out14
15
16nums = [4, 2, 2, 8, 3, 3, 1]17print("Before:", nums)18print("After: ", counting_sort(nums))
Run this code in the Python Playground

Counting Sort FAQ

What is the time complexity of counting sort?
Counting sort is O(n + k), where n is the number of elements and k is the range of possible values. When k = O(n) this is linear time. It uses O(n + k) extra space.
Is counting sort stable?
It can be. The stable version builds prefix sums of the counts and places elements from right to left, which preserves the relative order of equal keys. The simple "rewrite by value" version shown here produces a correct sort but is used mainly for plain integers.
When should I use counting sort?
Use it when sorting integers (or keys mappable to integers) within a small, known range. If the value range k is much larger than the number of elements, the count array wastes memory and a comparison sort is better.
What is the difference between counting sort and radix sort?
Counting sort sorts by the whole value in one pass and needs a count array as large as the value range. Radix sort sorts digit by digit and usually calls a stable counting sort on each digit, which keeps the per-pass range small (e.g. 10 for decimal digits). Radix sort handles large value ranges that would make a single counting sort impractical.
Why is counting sort not always faster than quicksort?
Counting sort is O(n + k), so it only wins when the value range k is comparable to n. If k is huge - say sorting 100 values in the range 0 to 1,000,000,000 - the O(k) count array dominates and wastes memory, while an O(n log n) comparison sort like quicksort stays fast and space-efficient.
Can counting sort handle negative numbers?
Yes, with a small offset. Instead of indexing the count array by the value directly, index it by value - min, so the smallest value maps to index 0. The count array size becomes max - min + 1. Forgetting this offset is a common bug that crashes on negative inputs.
Coddy programming languages illustration

Master algorithms with Coddy

GET STARTED