Sorting algorithms/Counting sort

From Rosetta Code
Revision as of 15:19, 19 May 2009 by rosettacode>ShinTakezou (with C code; i svcks in writing pseudocode, I know...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Task
Sorting algorithms/Counting sort
You are encouraged to solve this task according to the task description, using any language you may know.
This page uses content from Wikipedia. The original article was at Sorting algorithms/Counting sort. The list of authors can be seen in the page history. As with Rosetta Code, the text of Wikipedia is available under the GNU FDL. (See links for details on variance)

Implement the Counting sort. This is a way of sorting integers when the minimum and maximum value are known.

Pseudocode:

countingSort(array, min, max):
  count: array of (max - min + 1) elements
  initialize count with 0s
  foreach number in array:
    count[number - min] := count[number - min] + 1
  end foreach
  z := 0
  for i from min to max:
    while ( count[i - min] > 0 )
      array[z] := i
      z := z + 1
      count[i - min] := count[i - min] - 1
    end while
  end for
end countingSort

The min and max can be computed apart, or be known a priori.

Note: we know that, given an array of integers, its maximum and minimum values can be always found; but if we imagine the worst case for an array of 32 bit integers, we see that in order to hold the counts, we need an array of 232 elements, i.e. we need, to hold a count value up to 232-1, more or less 16 Gbytes. So the counting sort is more practical when the range is (very) limited and minimum and maximum values are known a priori. (Anyway sparse arrays may limit the impact of the memory usage)

C

<lang c>#include <stdio.h>

  1. include <stdlib.h>

void counting_sort_mm(int *array, int n, int min, int max) {

 int i, j, z;
 int range = max - min + 1;
 int *count = malloc(range * sizeof(*array));
 for(i = 0; i < range; i++) count[i] = 0;
 for(i = 0; i < n; i++) count[ array[i] - min ]++;
 for(i = min, z = 0; i <= max; i++) {
   for(j = 0; j < count[i - min]; j++) {
     array[z++] = i;
   }
 } 
 free(count);

}

void counting_sort(int *array, int n) {

 int i, min, max;
 
 min = max = array[0];
 for(i=1; i < n; i++) {
   if ( array[i] < min ) {
     min = array[i];
   } else if ( array[i] > max ) {
     max = array[i];
   }
 }

}</lang>

Testing (we suppose the oldest human being is less than 140 years old).

<lang c>#define N 100

  1. define MAX_AGE 140

int main() {

 int ages[N], i;
 for(i=0; i < N; i++) ages[i] = rand()%MAX_AGE;
 counting_sort_mm(ages, N, 0, MAX_AGE);
 for(i=0; i < N; i++) printf("%d\n", ages[i]);
 return EXIT_SUCCESS;

}</lang>