Bird
Raised Fist0
DSA Cprogramming~15 mins

Counting Sort Algorithm in DSA C - Deep Dive

Choose your learning style10 modes available
Overview - Counting Sort Algorithm
What is it?
Counting Sort is a way to sort a list of numbers by counting how many times each number appears. It works best when the numbers are within a small range. Instead of comparing numbers directly, it uses their counts to place them in order. This makes sorting very fast for certain types of data.
Why it matters
Without Counting Sort, sorting numbers with many repeats or within a small range would take longer using usual methods. Counting Sort solves this by using counting instead of comparing, making sorting faster and more efficient. This helps in situations like sorting exam scores or ages where values repeat and are limited.
Where it fits
Before learning Counting Sort, you should know basic sorting methods like Bubble Sort or Selection Sort. After this, you can learn more advanced sorting algorithms like Radix Sort or Bucket Sort that build on similar ideas.
Mental Model
Core Idea
Counting Sort sorts numbers by counting how many times each value appears and then placing them in order based on these counts.
Think of it like...
Imagine you have a box of colored balls and you want to arrange them by color. Instead of sorting each ball one by one, you count how many balls of each color you have, then line them up color by color using the counts.
Input Array: [4, 2, 2, 8, 3, 3, 1]

Count Array (index = number):
Index: 0 1 2 3 4 5 6 7 8
Count: 0 1 2 2 1 0 0 0 1

Output Array (sorted): [1, 2, 2, 3, 3, 4, 8]
Build-Up - 6 Steps
1
FoundationUnderstanding Counting Sort Basics
πŸ€”
Concept: Counting Sort uses a count array to track how many times each number appears.
Given an array of numbers, create a count array where each index represents a number in the input range. Increase the count at the index for each number found. This count array helps us know the frequency of each number.
Result
A count array showing how many times each number appears.
Understanding that counting frequencies is the key step helps see why Counting Sort avoids direct comparisons.
2
FoundationBuilding the Output Using Counts
πŸ€”
Concept: Use the count array to place numbers in the correct sorted position.
After counting, transform the count array to hold the position of each number in the output. Then, iterate the input array backward, placing each number at its correct position in the output array and decreasing the count.
Result
A sorted output array built from counts.
Knowing how counts translate to positions is crucial to reconstruct the sorted array correctly.
3
IntermediateHandling Range and Indexing
πŸ€”Before reading on: Do you think Counting Sort works for negative numbers without changes? Commit to yes or no.
Concept: Counting Sort requires the input numbers to be non-negative or adjusted to fit the count array indexing.
Since the count array uses numbers as indexes, negative numbers cause problems. To handle negatives, find the minimum value and shift all numbers by that amount to make them non-negative before counting.
Result
Counting Sort can handle negative numbers by shifting values.
Understanding the need for shifting helps apply Counting Sort beyond simple positive ranges.
4
IntermediateTime and Space Complexity Analysis
πŸ€”Before reading on: Is Counting Sort always faster than comparison sorts like Quick Sort? Commit to yes or no.
Concept: Counting Sort runs in linear time relative to input size and range but uses extra space proportional to the range.
Counting Sort takes O(n + k) time where n is input size and k is the range of input values. It uses extra space for the count array of size k. If k is much larger than n, Counting Sort becomes inefficient.
Result
Counting Sort is very fast for small ranges but can be slow or memory-heavy for large ranges.
Knowing the tradeoff between input size and range guides when to use Counting Sort effectively.
5
AdvancedStable Sorting with Counting Sort
πŸ€”Before reading on: Do you think Counting Sort preserves the order of equal elements by default? Commit to yes or no.
Concept: Counting Sort can be made stable by careful placement of elements using cumulative counts.
To make Counting Sort stable, transform the count array into a cumulative count array. This shows the final position of each number. Then place elements from the input array into the output array in reverse order, preserving original order for duplicates.
Result
A stable sorted array where equal elements keep their original order.
Understanding stability is important for sorting complex data where order matters.
6
ExpertOptimizing Counting Sort for Production
πŸ€”Before reading on: Do you think Counting Sort can be used directly for floating-point numbers? Commit to yes or no.
Concept: Counting Sort is limited to discrete integer ranges but can be adapted or combined with other algorithms for complex data.
Counting Sort is best for integers in a small range. For floating-point or large ranges, use it as a subroutine in Radix Sort or Bucket Sort. Also, optimize memory by using sparse data structures if the range is large but data is sparse.
Result
Counting Sort used efficiently in production by combining with other methods and memory optimizations.
Knowing Counting Sort's limits and how to extend it helps build powerful sorting pipelines.
Under the Hood
Counting Sort creates a frequency map of input values using an array indexed by the values themselves. It then converts this frequency map into a cumulative count array that tells where each value should be placed in the output. By iterating the input backward and placing elements according to cumulative counts, it builds a sorted array without comparisons.
Why designed this way?
Counting Sort was designed to sort integers quickly when the range is small, avoiding the overhead of comparison-based sorting. Using counts and positions leverages direct indexing for speed. Alternatives like comparison sorts were slower for such cases, and Counting Sort fills this niche efficiently.
Input Array
  ↓
Count Array (frequency)
  ↓ (cumulative sum)
Position Array
  ↓
Output Array (sorted)

Flow:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Input Array β”‚
β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
      β”‚
      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Count Array β”‚
β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
      β”‚ cumulative sum
      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Position Arrayβ”‚
β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
      β”‚
      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Output Arrayβ”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Myth Busters - 4 Common Misconceptions
Quick: Does Counting Sort work efficiently for very large ranges with few elements? Commit to yes or no.
Common Belief:Counting Sort is always the fastest sorting method regardless of input range.
Tap to reveal reality
Reality:Counting Sort becomes inefficient and memory-heavy when the range of input values is much larger than the number of elements.
Why it matters:Using Counting Sort on large ranges wastes memory and slows down the program, making other sorts like Quick Sort better choices.
Quick: Is Counting Sort a comparison-based sorting algorithm? Commit to yes or no.
Common Belief:Counting Sort sorts by comparing elements like Quick Sort or Merge Sort.
Tap to reveal reality
Reality:Counting Sort does not compare elements; it uses counting and indexing to sort.
Why it matters:Misunderstanding this leads to confusion about Counting Sort's speed and when it can be applied.
Quick: Does Counting Sort handle negative numbers without modification? Commit to yes or no.
Common Belief:Counting Sort can sort any integers directly, including negatives.
Tap to reveal reality
Reality:Counting Sort requires shifting or adjustments to handle negative numbers because array indexes cannot be negative.
Why it matters:Failing to adjust for negatives causes errors or crashes in implementations.
Quick: Is Counting Sort stable by default? Commit to yes or no.
Common Belief:Counting Sort always preserves the order of equal elements.
Tap to reveal reality
Reality:Counting Sort is stable only if implemented with cumulative counts and backward iteration; otherwise, it may not be stable.
Why it matters:Stability matters when sorting complex data where order of equal keys must be preserved.
Expert Zone
1
Counting Sort's stability depends on the order of iteration when placing elements; backward iteration preserves stability.
2
The memory cost of Counting Sort can be reduced by using hash maps or sparse arrays when the input range is large but data is sparse.
3
Counting Sort is often used as a subroutine in Radix Sort to handle each digit efficiently, combining linear time sorting with large number support.
When NOT to use
Avoid Counting Sort when the input range is huge compared to the number of elements or when sorting non-integer data without adaptation. Use comparison-based sorts like Quick Sort or Merge Sort, or hybrid algorithms like Tim Sort instead.
Production Patterns
In production, Counting Sort is used for sorting small-range integer data like ages, grades, or pixel values. It is also a core part of Radix Sort implementations for sorting large integers or strings efficiently.
Connections
Radix Sort Algorithm
Counting Sort is used as a stable subroutine within Radix Sort to sort digits.
Understanding Counting Sort helps grasp how Radix Sort achieves linear time sorting for large numbers by sorting digit by digit.
Histogram Equalization in Image Processing
Both use counting frequencies of values to redistribute or reorder data.
Knowing Counting Sort's frequency counting clarifies how histograms are used to adjust image brightness and contrast.
Inventory Management Systems
Counting Sort's frequency counting is similar to tracking stock quantities for items.
Recognizing counting as a core operation links sorting algorithms to real-world inventory tracking and optimization.
Common Pitfalls
#1Trying to use Counting Sort directly on negative numbers without adjustment.
Wrong approach:int min = findMin(arr, n); // No shifting applied int count[MAX_RANGE]; // Counting using arr[i] as index directly count[arr[i]]++;
Correct approach:int min = findMin(arr, n); // Shift values to non-negative int shift = -min; int count[MAX_RANGE]; count[arr[i] + shift]++;
Root cause:Misunderstanding that array indexes cannot be negative causes incorrect indexing and runtime errors.
#2Not making Counting Sort stable when sorting data with equal keys.
Wrong approach:for (int i = 0; i < n; i++) { output[count[arr[i]] - 1] = arr[i]; count[arr[i]]--; }
Correct approach:for (int i = n - 1; i >= 0; i--) { output[count[arr[i]] - 1] = arr[i]; count[arr[i]]--; }
Root cause:Placing elements in forward order breaks stability because later duplicates overwrite earlier ones.
#3Using Counting Sort on data with a very large range causing memory overflow.
Wrong approach:int count[1000000000]; // Large range count array allocated
Correct approach:Use comparison-based sort like Quick Sort or hybrid algorithms when range is too large.
Root cause:Ignoring memory constraints and input characteristics leads to inefficient or failing programs.
Key Takeaways
Counting Sort sorts by counting how many times each number appears and uses these counts to place numbers in order without comparisons.
It works best when the input numbers are integers within a small range and can be unstable if not implemented carefully.
Adjustments are needed to handle negative numbers by shifting values to non-negative indexes.
Counting Sort runs in linear time relative to input size and range but uses extra memory proportional to the range.
It is often used as a building block in more complex sorting algorithms like Radix Sort for efficient large number sorting.

Practice

(1/5)
1. What is the main idea behind the Counting Sort algorithm?
easy
A. Counting the number of occurrences of each element to sort
B. Comparing each element with every other element
C. Dividing the array into halves and sorting recursively
D. Swapping adjacent elements repeatedly

Solution

  1. Step 1: Understand Counting Sort principle

    Counting Sort counts how many times each value appears in the input.
  2. Step 2: Use counts to place elements in order

    Using these counts, it places elements directly into the sorted output.
  3. Final Answer:

    Counting the number of occurrences of each element to sort -> Option A
  4. Quick Check:

    Counting occurrences = A [OK]
Hint: Counting occurrences helps sort without comparisons [OK]
Common Mistakes:
  • Thinking it compares elements like bubble sort
  • Confusing with divide and conquer methods
  • Assuming it swaps elements repeatedly
2. Which of the following is the correct way to declare the count array in C for counting sort if the maximum value in input is max_val?
easy
A. int count[max_val + 1];
B. int count[max_val];
C. int count[max_val - 1];
D. int count[max_val * 2];

Solution

  1. Step 1: Understand array size for counts

    The count array must hold counts for all values from 0 to max_val inclusive, so size is max_val + 1.
  2. Step 2: Choose correct declaration

    Declaring int count[max_val + 1]; ensures space for all possible values.
  3. Final Answer:

    int count[max_val + 1]; -> Option A
  4. Quick Check:

    Count array size = max_val + 1 [OK]
Hint: Count array size must cover all values including max_val [OK]
Common Mistakes:
  • Using max_val size misses last element count
  • Using max_val - 1 causes out-of-range errors
  • Using double size wastes memory unnecessarily
3. What will be the output of the counting sort on the array [4, 2, 2, 8, 3, 3, 1]?
medium
A. [1, 3, 2, 4, 8, 3, 2]
B. [1, 2, 2, 3, 3, 4, 8]
C. [8, 4, 3, 3, 2, 2, 1]
D. [2, 2, 3, 3, 4, 8, 1]

Solution

  1. Step 1: Count occurrences of each element

    1 appears once, 2 appears twice, 3 appears twice, 4 once, 8 once.
  2. Step 2: Place elements in sorted order using counts

    Sorted array is [1, 2, 2, 3, 3, 4, 8].
  3. Final Answer:

    [1, 2, 2, 3, 3, 4, 8] -> Option B
  4. Quick Check:

    Sorted array = C [OK]
Hint: Count then output in order for sorted array [OK]
Common Mistakes:
  • Confusing input order with output order
  • Forgetting to repeat elements by their counts
  • Mixing up counts and positions
4. Given the following code snippet for counting sort, what is the error?
int count[5] = {0};
int arr[6] = {1, 3, 4, 2, 3, 0};
for (int i = 0; i < 6; i++) {
    count[arr[i]]++;
}
for (int i = 0; i <= 5; i++) {
    printf("%d ", count[i]);
}
medium
A. Incrementing count[arr[i]] is wrong
B. Count array not initialized to zero
C. Array arr size is incorrect
D. Loop accessing count array goes out of bounds

Solution

  1. Step 1: Check count array size and loop range

    Count array size is 5 (indices 0 to 4), but loop runs i from 0 to 5 inclusive, accessing count[5] which is out of bounds.
  2. Step 2: Identify out-of-bounds access

    Accessing count[5] causes undefined behavior or error.
  3. Final Answer:

    Loop accessing count array goes out of bounds -> Option D
  4. Quick Check:

    Loop index > count size = D [OK]
Hint: Check array size vs loop limits carefully [OK]
Common Mistakes:
  • Ignoring array size when looping
  • Assuming initialization fixes out-of-bounds
  • Confusing arr size with count size
5. You want to sort an array containing negative and positive integers using counting sort. Which modification is necessary?
hard
A. Use the array as is because counting sort handles negatives naturally
B. Sort only positive numbers and ignore negatives
C. Shift all numbers by adding the absolute value of the minimum element before sorting
D. Use bubble sort instead

Solution

  1. Step 1: Understand counting sort limitation

    Counting sort works only with non-negative integers because it uses array indices as counts.
  2. Step 2: Adjust negative values for indexing

    Shift all numbers by adding the absolute value of the minimum element to make all values non-negative before counting.
  3. Final Answer:

    Shift all numbers by adding the absolute value of the minimum element before sorting -> Option C
  4. Quick Check:

    Shift negatives to non-negative = B [OK]
Hint: Shift negatives to zero or above before counting [OK]
Common Mistakes:
  • Trying to count negatives directly
  • Ignoring negative values in input
  • Switching to other sorts unnecessarily
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard