排序算法——计数排序

来源:互联网 发布:后期特效制作软件 编辑:程序博客网 时间:2024/04/30 01:52

计数排序是一个非基于比较的线性时间排序算法。它对输入的数据有附加的限制条件:
1、输入的线性表的元素属于有限偏序集S;
2、设输入的线性表的长度为n,|S|=k(表示集合S中元素的总数目为k),则k=O(n)。
在这两个条件下,计数排序的复杂性为O(n+k)。

计数排序算法的基本思想是对于给定的输入序列中的每一个元素x,确定该序列中值小于x的元素的个数。一旦有了这个信息,就可以将x直接存放到最终的输出序列的正确位置上。当然,如果有多个元素具有相同的值时,我们不能将这些元素放在输出序列的同一个位置上,因此,上述方案还要作适当的修改。

计数排序是稳定的排序算法。

Code:
  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3.   
  4. void counting_sort(int a[], int size)   
  5. {   
  6.     int i, j, min, max, range;   
  7.     int *c, *b;   
  8.        
  9.     min = max = a[0];                              
  10.     for (i = 1; i < size; i++) {/* find the range of input list */  
  11.         if (a[i] < min) {   
  12.             min = a[i];   
  13.         } else if (a[i] > max) {   
  14.             max = a[i];   
  15.         }   
  16.     }   
  17.     range = max - min + 1;   
  18.     c = (int *)malloc(range * sizeof(int));/* for temporary storage */  
  19.     b = (int *)malloc(size * sizeof(int)); /* for storage sorted list */  
  20.   
  21.     for (i = 0; i < range; i++) {   
  22.         c[i] = 0;   
  23.     }   
  24.   
  25.     /* c[i] include the num of elements which equal to i */  
  26.     for (j = 0; j < size; j++) {   
  27.         c[a[j] - min] += 1;   
  28.     }   
  29.   
  30.     /* c[i] include the num of elements which less or equal than i */  
  31.     for (i = 1; i < range; i++) {   
  32.         c[i] += c[i-1];   
  33.     }   
  34.   
  35.     for (j = size - 1; j >= 0; j--) {   
  36.         b[c[a[j] - min] - 1] = a[j];/* for c style */  
  37.         c[a[j] - min] -= 1;   
  38.     }   
  39.        
  40.     /* input sorted list to array a. not necessary, we can return the address of array b */  
  41.     for (i = 0; i < size; i++)   
  42.         a[i] = b[i]; 
  43.     free(b);
  44.     free(c);  
  45. }   
  46.   
  47. main()   
  48. {   
  49.     int a[] = {4, 1, 3, 4, 3}, i;   
  50.     int size = sizeof(a) / sizeof(int);   
  51.     counting_sort(a, size);   
  52.   
  53.     for (i = 0; i < size; i++)   
  54.         printf("%d ", a[i]);   
  55. }  

由于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

原创粉丝点击