Counting Sort
Table of Contents
Counting Sort
Counting Sort is a non-comparison-based sorting algorithm that works efficiently when the range of input values is known and relatively small. It counts the occurrences of each value in the input array and uses this information to place elements directly into their correct positions in the output array. It’s particularly effective for integers or objects that can be mapped to integers within a limited range.
Pseudocode for Counting Sort
CountingSort(arr, n, k):
// Input: array arr of size n, elements in range [0, k]
// Output: sorted array
// Step 1: Initialize count array
count = array of size k+1 initialized to 0
// Step 2: Count occurrences of each element
for i from 0 to n-1:
count[arr[i]] = count[arr[i]] + 1
// Step 3: Compute cumulative counts
for i from 1 to k:
count[i] = count[i] + count[i-1]
// Step 4: Build output array
output = array of size n
for i from n-1 down to 0:
output[count[arr[i]] - 1] = arr[i]
count[arr[i]] = count[arr[i]] - 1
return output
Example
Consider the array: [4, 2, 2, 8, 3, 3, 1]
Assume the elements are integers in the range [0, 8], so k = 8.
Step-by-Step Process
-
Initialize Count Array:
- Create
count = [0, 0, 0, 0, 0, 0, 0, 0, 0](sizek+1 = 9for values 0 to 8).
- Create
-
Count Occurrences:
- For each element in
arr, increment the corresponding index incount:arr[0] = 4:count[4] += 1→count = [0, 0, 0, 0, 1, 0, 0, 0, 0]arr[1] = 2:count[2] += 1→count = [0, 0, 1, 0, 1, 0, 0, 0, 0]arr[2] = 2:count[2] += 1→count = [0, 0, 2, 0, 1, 0, 0, 0, 0]arr[3] = 8:count[8] += 1→count = [0, 0, 2, 0, 1, 0, 0, 0, 1]arr[4] = 3:count[3] += 1→count = [0, 0, 2, 1, 1, 0, 0, 0, 1]arr[5] = 3:count[3] += 1→count = [0, 0, 2, 2, 1, 0, 0, 0, 1]arr[6] = 1:count[1] += 1→count = [0, 1, 2, 2, 1, 0, 0, 0, 1]
- For each element in
-
Compute Cumulative Counts:
- Update
countso each index stores the sum of counts up to that index:count[0] = 0count[1] = 0 + 1 = 1count[2] = 1 + 2 = 3count[3] = 3 + 2 = 5count[4] = 5 + 1 = 6count[5] = 6 + 0 = 6count[6] = 6 + 0 = 6count[7] = 6 + 0 = 6count[8] = 6 + 1 = 7
- Result:
count = [0, 1, 3, 5, 6, 6, 6, 6, 7] - This indicates where each value should be placed in the output array.
- Update
-
Build Output Array:
- Initialize
output = [_, _, _, _, _, _, _](sizen = 7). - Process
arrfrom right to left:arr[6] = 1:count[1] = 1, place1atoutput[0], decrementcount[1]to 0.arr[5] = 3:count[3] = 5, place3atoutput[4], decrementcount[3]to 4.arr[4] = 3:count[3] = 4, place3atoutput[3], decrementcount[3]to 3.arr[3] = 8:count[8] = 7, place8atoutput[6], decrementcount[8]to 6.arr[2] = 2:count[2] = 3, place2atoutput[2], decrementcount[2]to 2.arr[1] = 2:count[2] = 2, place2atoutput[1], decrementcount[2]to 1.arr[0] = 4:count[4] = 6, place4atoutput[5], decrementcount[4]to 5.
- Resulting
output = [1, 2, 2, 3, 3, 4, 8].
- Initialize
-
Sorted Array:
[1, 2, 2, 3, 3, 4, 8]
Complexity analysis
- Time Complexity:
- O(n + k), where
nis the number of elements andkis the range of input values (max value + 1). - Efficient when
kis not significantly larger thann.
- O(n + k), where
- Space Complexity: O(n + k) for the output and count arrays.
- Stability: Stable (maintains relative order of equal elements) if implemented as shown.
- Advantages: Extremely fast for small ranges of integers, stable, and linear time when
kis small. - Disadvantages: Requires extra space, only works for non-negative integers or mappable values, inefficient if
kis very large.
Notes
- Counting Sort is often used as a subroutine in Radix Sort to handle digits of integers.
- If the input includes negative numbers or non-integers, preprocess them (e.g., shift negative numbers by adding the minimum value or map to integers).
- The algorithm assumes the range of values (
k) is known in advance.