Back to Python
2026-03-207 min read

Counting Sort (Python Programming)

Learn Counting Sort (Python Programming) step by step with clear examples and exercises.

Title: Mastering Counting Sort in Python: A full guide

Why This Matters

Counting Sort is a powerful sorting algorithm that shines when handling large datasets with uniform distribution. Understanding Counting Sort will arm you with essential skills for tackling complex problems, enhancing your coding abilities, and preparing for interviews.

The Advantages of Counting Sort

Counting Sort offers several advantages:

  1. Efficient handling of large datasets (O(n + k) time complexity)
  2. Suitable for uniformly distributed data
  3. Simple implementation in various programming languages, including Python
  4. Useful in applications like data compression, network routing, and database management systems
  5. Can be optimized for extremely large datasets using external memory or parallelization
  6. Offers a stable sort (maintains the original order of equal elements)

Prerequisites

To follow this guide, you should have a good understanding of the following concepts:

  1. Basic Python programming (variables, loops, functions)
  2. Lists and arrays in Python
  3. Understanding of big O notation
  4. Familiarity with sorting algorithms like Bubble Sort, Merge Sort, Quick Sort, and Heap Sort
  5. Knowledge of data structures such as dictionaries and lists comprehensions
  6. Familiarity with the concept of external memory (optional but useful for handling extremely large datasets)
  7. Understanding of parallel programming concepts (optional but useful for optimizing Counting Sort)

Core Concept

Counting Sort works by counting the occurrences of each element in an input array and then placing them in sorted order. Here's a step-by-step breakdown:

  1. Create an array, count[], of size equal to the maximum value that can be stored in the input array plus one. Initialize all elements to zero.
  2. Create an array, output[], also of the same size as the input array.
  3. Iterate through the input array and increment the corresponding index in the count array for each element.
  4. Iterate through the count array and calculate the cumulative sum of all elements up to that point. Store these values in a new array, cumulative[].
  5. Now iterate through the input array again and use the cumulative sums to find the position for each element in the output array. Place the element at this position.
  6. Finally, copy the contents of the output array back to the original input array, and you have a sorted array.

Understanding the Algorithm's Workings

Let's look at deeper into Counting Sort:

  1. Initialization: We create two arrays, count[] and cumulative[], of size (max(arr) + 1). Both arrays are initialized to zeros.
  2. Counting: We iterate through the input array and increment the corresponding index in the count array for each element. This gives us a count of how many times each value appears in the input array.
  3. Cumulative Sums: We calculate the cumulative sum of all elements up to that point in the count array and store these values in the cumulative array.
  4. Placement: We iterate through the input array again, using the cumulative sums to find the position for each element in the output array. We place the element at this position.
  5. Sorting: Finally, we copy the contents of the output array back to the original input array, and we have a sorted array.

Worked Example

Let's sort the following array using Counting Sort:

arr = [1, 6, 3, 1, 5, 7, 2, 8, 4, 2, 5, 6]
n = len(arr)
output = [0] * n
count = [0] * (max(arr) + 1)
cumulative = [0] * (max(arr) + 1)

Step 1: Initialize count and cumulative arrays

for i in range(n):

count[arr[i]] += 1

Step 2: Calculate cumulative sums

for i in range(1, len(count)):

count[i] = count[i] + count[i-1]

Step 3: Place elements in output array according to their counts

for i in range(n - 1, -1, -1):

outputIndex = count[arr[i]] - 1

arr[outputIndex], arr[i] = arr[i], arr[outputIndex]

count[arr[i]] -= 1

Step 4: Copy sorted array back to original array

for i in range(n):

arr[i] = output[i]


### Optimizing Counting Sort for Large Datasets

To handle extremely large datasets, you can optimize Counting Sort by using external memory or parallelizing the algorithm. External memory techniques involve reading and writing data from disk to reduce memory usage, while parallelization involves distributing the workload across multiple processors to speed up computation.

Common Mistakes

  1. Forgetting to initialize the cumulative array: It's crucial to calculate cumulative sums for correct positioning of elements in the output array.
  2. Incorrect initialization of the count and output arrays: Make sure you initialize both arrays with zeros and ensure they have the same size as the input array.
  3. Not handling negative numbers: Counting Sort doesn't work well with negative numbers, so it's best to exclude them from the input array or handle them separately.
  4. Misunderstanding the time complexity: Remember that the time complexity of Counting Sort is O(n + k), where n is the number of elements and k is the range of input values.
  5. Not properly implementing the sorting step: Make sure to iterate through the input array in reverse order when placing elements in the output array.
  6. ### Handling Negative Numbers
  • To handle negative numbers, you can create two separate arrays for positive and negative numbers, respectively.
  1. ### Using Python Generators
  • Implementing Counting Sort with Python generators can help save memory usage by avoiding the need to store all intermediate values in memory at once.
  1. ### Sorting Strings Lexicographically
  • To sort an array of strings lexicographically, you can convert each string to a list of characters and apply Counting Sort on the lists of characters. Then, concatenate the sorted lists back into strings.
  1. ### Sorting in Descending Order
  • To sort an array in descending order, simply change the comparison operator from < to > throughout the algorithm.
  1. ### Implementing a Single-Pass Version (Radix Sort)
  • Radix Sort is an extension of Counting Sort that sorts multi-digit numbers in a single pass by sorting each digit separately. This can be more efficient for large datasets with non-uniform distribution.

Practice Questions

  1. Implement Counting Sort for the following input array: [9, 3, 6, 2, 8, 7, 4, 5, 1]
  2. Modify the Counting Sort algorithm to handle negative numbers and sort the following array: [-5, -2, 4, 0, 8, -3, 6, 9, -1]
  3. Write a Python function that sorts an array of strings lexicographically using Counting Sort. Test your function with the following array: ['apple', 'banana', 'kiwi', 'mango', 'orange']
  4. Implement a parallel version of Counting Sort for the input array in question 1, using Python's multiprocessing module.
  5. Optimize the Counting Sort algorithm to handle extremely large datasets by implementing an external memory solution.

FAQ

  1. What is the time complexity of Counting Sort? The time complexity of Counting Sort is O(n + k), where n is the number of elements and k is the range of input values.
  2. Can Counting Sort handle negative numbers? No, Counting Sort does not work well with negative numbers. You can handle them by creating separate arrays for positive and negative numbers or by using other sorting algorithms like Quick Sort that are suitable for mixed data types.
  3. What is the space complexity of Counting Sort? The space complexity of Counting Sort is O(k), where k is the range of input values. This makes it suitable for handling large datasets with uniform distribution.
  4. How can I optimize Counting Sort for extremely large datasets? To handle extremely large datasets, you can use external memory techniques or parallelize the algorithm to distribute the workload across multiple processors.
  5. What are some real-world applications of Counting Sort? Counting Sort is useful in data compression, network routing, and database management systems. It can also be applied in fields like genomics, finance, and computer graphics for tasks such as sorting large datasets, scheduling jobs, and optimizing algorithms.
  6. How does Counting Sort compare to other sorting algorithms? Compared to other sorting algorithms like Bubble Sort, Merge Sort, Quick Sort, and Heap Sort, Counting Sort offers better performance for uniformly distributed data with large ranges (O(n + k) time complexity). However, it may not be as efficient for non-uniformly distributed data or small datasets.
  7. What is the difference between Counting Sort and Radix Sort? Counting Sort sorts elements based on their counts in an auxiliary array, while Radix Sort sorts multi-digit numbers by sorting each digit separately using a counting-based approach. Radix Sort can be considered an extension of Counting Sort for handling multi-digit numbers more efficiently.
  8. Can I implement Counting Sort with Python generators? Yes, you can implement Counting Sort with Python generators to save memory usage by avoiding the need to store all intermediate values in memory at once. This can be particularly useful when dealing with extremely large datasets.
Counting Sort (Python Programming) | Python | XQA Learn