What is a counting sort algorithm?

Counting sort is one of the most famous sorting algorithms. It​ performs some arithmetic calculations in order to get the perfect output sequence. It can be applied to all the values that we can use as an index.

Algorithm

Consider the following algorithm:

The above algorithm is illustrated in the example below:

1 of 5

Code

Let’s implement the above algorithm.

#include<iostream>
#include<algorithm>
using namespace std;
// function for printing an array.
void printArr(int *array, int size) {
for(int i = 0; i < size; i++)
cout << array[i] << " ";
cout << endl;
}
// function for calculating maximum element.
int findMax(int array[], int size) {
int max = array[0];
for(int i = 1; i < size; i++) {
if(array[i] > max)
max = array[i];
}
return max;
}
// function for the count sort algorithm
void countSort(int *array, int size) {
int output[size];
int max = findMax(array, size);
int count[max+1];
for(int i = 0; i <= max; i++)
count[i] = 0; //initialize frequencies array to all zero
for(int i = 0; i < size; i++)
count[array[i]]++; //fill the array with the count of each number
for(int i = 1; i <= max; i++)
count[i] += count[i-1]; //find cumulative frequency
for(int i = size - 1 ; i>=0; i--) {
output[count[array[i]]-1] = array[i];
count[array[i]] -= 1; //decrease count for same numbers
}
for(int i = 0; i < size; i++) {
array[i] = output[i]; //store output array to main array
}
}
int main() {
int arr[] = {1, 5, 9, 8, 1, 3};
int n = 6;
cout << "Array before Sorting: ";
printArr(arr, n);
countSort(arr, n);
cout << "Array after Sorting: ";
printArr(arr, n);
}
Counting sort

Explanation

In the above code:

  • Lines 6–10: We define printArr function to print the array.
  • Lines 13–20: We define a findMax function to find the maximum value of the array.
  • Lines 26–27: We find the maximum number and create an array of size max+1.
  • Lines 29–34: We store the frequency of each number and calculate the accumulative frequency.
  • Lines 36–39: We sort the values at their position in the output array.
  • Lines 41–43: We copy the sorted output array in the input array.

How to handle negative values and ranges with a larger minimum value?

We can see one drawback here, that if the minimum value is 10001000, the first 10001000 indexes of the frequency array will not be used and it will increase the space complexity. Let’s do a little trick here.

  • Find the minimum value of the array and subtract it from all elements of the array. By doing this, the range of the array will be always from 00 to (maximumminimummaximum - minimum).
  • Apply counting sort.
  • Add the number we subtracted in the first step.

Now we can handle the negative integer values as well. See the following code:

#include<iostream>
#include<algorithm>
using namespace std;
// function for printing an array.
void printArr(int *array, int size) {
for(int i = 0; i<size; i++)
cout << array[i] << " ";
cout << endl;
}
// function for calculating maximum element.
int findMax(int array[], int size) {
int max = array[0];
for(int i = 1; i < size; i++) {
if(array[i] > max)
max = array[i];
}
return max;
}
// function for calculating minimum element.
int findMin(int array[], int size) {
int min = array[0];
for(int i = 1; i < size; i++) {
if(array[i] < min)
min = array[i];
}
return min;
}
// function for the count sort algorithm
void countSort(int *array, int size) {
int output[size];
int min = findMin(array, size);
for(int i = 0; i < size; i++)
array[i]-=min; // subtracting minimum value from the array to start range from 0
int max = findMax(array, size);
int count[max+1];
for(int i = 0; i<=max; i++)
count[i] = 0; //initialize frequencies array to all zero
for(int i = 0; i < size; i++)
count[array[i]]++; //fill the array with the count of each number
for(int i = 1; i<=max; i++)
count[i] += count[i-1]; //find cumulative frequency
for(int i = size - 1 ; i>=0; i--) {
output[count[array[i]]-1] = array[i];
count[array[i]] -= 1; //decrease count for same numbers
}
for(int i = 0; i < size; i++) {
array[i] = output[i] + min; //store output array to main array with the actual values
}
}
int main() {
int arr[] = {1, 5, 9, 8, -1, -3};
int n = 6;
cout << "Array before Sorting: ";
printArr(arr, n);
countSort(arr, n);
cout << "Array after Sorting: ";
printArr(arr, n);
}
Optimized counting sort

In the above playground:

  • Lines 23–30: We define findMin function to find the minimum value.
  • Lines 35-37: We subtract the min value from each element of the array.
  • Line 55: We add the subtracted min value to the sorted array.

Time complexity

We can see two different loops here. One till the number of elements in the array (nn) and the other till the range (kk). So, This algorithm works in O(n+k)O(n+k).

Space complexity

We are creating two extra arrays. One to store the sorted array (nn) and the other to store the frequency of each element in the range (rr). So, the space complexity is O(n+r)O(n+r).

Copyright ©2024 Educative, Inc. All rights reserved