Counting Sort is a simple and intuitive non-comparison sorting algorithm. It determines the position of elements in the sorted array by counting the occurrences of each element and then using these counts. This algorithm is highly efficient when the element range is small and there are many repeated elements, making it ideal for beginners to understand and implement.
Core Algorithm Idea¶
- Determine Element Range: Find the minimum value
minand maximum valuemaxin the array to define the element range as[min, max]. - Count Element Frequencies: Create a count array with length
max - min + 1to record the frequency of each element. - Compute Prefix Sums: Convert the count array into a prefix sum array, where each value at position
iindicates the last position of the elementmin + iin the sorted array. - Generate Sorted Result: Traverse the original array from the end to place elements into the result array based on their mapped positions and prefix sums, ensuring stability.
Code Implementation Steps¶
1. Handle Edge Cases¶
If the array is empty or has only one element, return immediately as no sorting is needed.
2. Determine Element Range¶
Traverse the array to find the minimum min and maximum max values, then calculate the range size as max - min + 1.
3. Count Element Frequencies¶
Create a count array of length max - min + 1. For each element num in the original array, increment count[num - min] (mapping to non-negative indices to avoid negative values).
4. Compute Prefix Sums¶
Accumulate the count array to determine the last position of each element in the sorted array.
5. Generate Sorted Result¶
Traverse the original array from the end. For each element num, place it in the result array at position count[num - min] - 1, then decrement the count to maintain stability for repeated elements.
Java Code Implementation¶
import java.util.Arrays;
public class CountingSort {
public static void countingSort(int[] arr) {
// Edge case handling: no sorting needed for empty or single-element array
if (arr == null || arr.length <= 1) {
return;
}
// Step 1: Find the minimum and maximum values in the array
int min = arr[0];
int max = arr[0];
for (int num : arr) {
if (num < min) min = num;
if (num > max) max = num;
}
// Step 2: Create a count array with length (max - min + 1)
int[] count = new int[max - min + 1];
// Step 3: Count occurrences of each element
for (int num : arr) {
count[num - min]++; // Map elements to non-negative indices
}
// Step 4: Compute prefix sums to determine the last position of each element
for (int i = 1; i < count.length; i++) {
count[i] += count[i - 1];
}
// Step 5: Generate the sorted result array (traverse from the end to ensure stability)
int[] result = new int[arr.length];
for (int i = arr.length - 1; i >= 0; i--) {
int num = arr[i];
int k = num - min; // Index in the count array
result[count[k] - 1] = num; // Place the element in the correct position
count[k]--; // Decrement count for subsequent duplicates
}
// Copy the result back to the original array
System.arraycopy(result, 0, arr, 0, arr.length);
}
// Test code
public static void main(String[] args) {
int[] arr = {4, 2, 2, 8, 3, 3, 1};
System.out.println("Before sorting: " + Arrays.toString(arr));
countingSort(arr);
System.out.println("After sorting: " + Arrays.toString(arr));
}
}
Code Explanation¶
- Frequency Counting: Mapping elements using
num - minensures non-negative indices, avoiding negative index issues. For example, element2withmin=1maps to index1(2-1=1). - Prefix Sum Calculation: The accumulated count array gives the last position of each element. For
[1,2,2,3,3,4,8]withmin=1, the prefix sum array is[1,3,5,6,6,6,6,7], wherecount[2]=5means element3(i.e.,min+2=3) ends at position4(5-1). - Stability: Traversing from the end preserves the relative order of duplicates. For example, two
2s in the original array will be placed in positions1and2of the result array in their original order.
Complexity Analysis¶
- Time Complexity: O(n + k), where
nis the array length andkis the element range (max - min + 1). The algorithm runs in three linear passes: counting, prefix sum calculation, and result generation. - Space Complexity: O(n + k), due to the additional count and result arrays.
Applicable Scenarios¶
- Elements are integers with a small range (e.g., student scores, ages).
- Repeated elements are frequent, and relative order preservation (stability) is required.
Counting Sort achieves sorting through simple counting and summation operations without complex comparison logic, making it an excellent introduction to sorting algorithms for beginners.