计数排序是一个非基于比较的线性时间排序算法。它对输入的数据有附加的限制条件:
1、输入的线性表的元素属于有限偏序集S;
2、设输入的线性表的长度为n,|S|=k(表示集合S中元素的总数目为k),则k=O(n)。
在这两个条件下,计数排序的复杂性为O(n+k)。
计数排序算法的基本思想是对于给定的输入序列中的每一个元素x,确定该序列中值小于x的元素的个数。一旦有了这个信息,就可以将x直接存放到最终的输出序列的正确位置上。当然,如果有多个元素具有相同的值时,我们不能将这些元素放在输出序列的同一个位置上,因此,上述方案还要作适当的修改。
计数排序是稳定的排序算法。
- #include <stdio.h>
- #include <stdlib.h>
- void counting_sort(int a[], int size)
- {
- int i, j, min, max, range;
- int *c, *b;
- min = max = a[0];
- for (i = 1; i < size; i++) {/* find the range of input list */
- if (a[i] < min) {
- min = a[i];
- } else if (a[i] > max) {
- max = a[i];
- }
- }
- range = max - min + 1;
- c = (int *)malloc(range * sizeof(int));/* for temporary storage */
- b = (int *)malloc(size * sizeof(int)); /* for storage sorted list */
- for (i = 0; i < range; i++) {
- c[i] = 0;
- }
- /* c[i] include the num of elements which equal to i */
- for (j = 0; j < size; j++) {
- c[a[j] - min] += 1;
- }
- /* c[i] include the num of elements which less or equal than i */
- for (i = 1; i < range; i++) {
- c[i] += c[i-1];
- }
- for (j = size - 1; j >= 0; j--) {
- b[c[a[j] - min] - 1] = a[j];/* for c style */
- c[a[j] - min] -= 1;
- }
- /* input sorted list to array a. not necessary, we can return the address of array b */
- for (i = 0; i < size; i++)
- a[i] = b[i];
- free(b);
- free(c);
- }
- main()
- {
- int a[] = {4, 1, 3, 4, 3}, i;
- int size = sizeof(a) / sizeof(int);
- counting_sort(a, size);
- for (i = 0; i < size; i++)
- printf("%d ", a[i]);
- }
由于C数组的下标由0开始,这里用到下标转换有点麻烦
a:index 0 1 2 3 4
value 4 1 3 4 3
c:index 0 1 2 3
value 1 0 2 2 (code 26-28)
value 1 1 3 5 (code 31-33)
b:index 0 1 2 3 4
value 1 3 3 4 4