(1.3.6)线性排序:计数排序

来源:互联网 发布:淘宝商品批量上传 编辑:程序博客网 时间:2024/05/23 20:17

前言

一般的排序都是需要进行关键字的比较的。有没有不需要比较的的呢?有的,计数排序就是其中一种。

计数排序

假设输入序列都是0到k之间的整数,则可使用计数排序。具体操作是这样的:创建一个同类型同等大小的临时数组temp,用于备份输入序列。创建一个整型大小为k的数组count,用于统计序列中各元素出现的次数。接下来只需把备份序列从大到小放回原数组即可。一个示例图:


仔细看图,很容易理解的。并且可以看出计数排序是稳定的,下面给出它的示例代码;

代码 

[cpp] view plaincopy
  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include<memory.h>  
  4. #include<time.h>  
  5. void print(int *a, int n)  
  6. {  
  7.     for (int i = 0; i < n; i++)  
  8.         printf("%4d",a[i]);  
  9.     printf("\n");  
  10. }  
  11. int get_max(int *a, int n)  
  12. {  
  13.     int max = a[0];  
  14.     for (int i = 1; i < n; i++)  
  15.     {  
  16.         if (a[i]>max)  
  17.             max = a[i];  
  18.     }  
  19.     //加一后返回  
  20.     return max+1;  
  21. }  
  22. /* 
  23. n是序列个数 
  24. max是序列中元素最大值[0,max) 
  25. */  
  26. void CountSort(int array[], int n, int max)  
  27. {  
  28.     int i;  
  29.     int *temp = (int*)malloc(n*sizeof(int));  
  30.     int *count = (int*)malloc(max*sizeof(int));  
  31.     //初始化临时数组  
  32.     memcpy(temp, array, n*sizeof(int));  
  33.     //初始化计数数组  
  34.     memset(count, 0, max*sizeof(int));  
  35.     //计数  
  36.     for (i = 0; i < n; i++)  
  37.         count[array[i]]++;  
  38.     //计算位置  
  39.     for (i = 1; i < max; i++)  
  40.         count[i] += count[i - 1];  
  41.     //回放序列,方向:从后往前  
  42.     for (i = n - 1; i >= 0; i--)  
  43.         array[--count[temp[i]]] = temp[i];  
  44.     //释放空间  
  45.     delete[]temp;  
  46.     delete[]count;  
  47. }  
  48. int main()  
  49. {  
  50.     printf("***计数排序***by David***\n");  
  51.     srand((unsigned)time(0));  
  52.     int a[] = {2,3,1,5,1,6,4,9};  
  53.     int n = sizeof(a) / sizeof(int);  
  54.     printf("原序列\n");  
  55.     print(a, n);  
  56.     printf("计数排序\n");  
  57.     CountSort(a, n, get_max(a, n));  
  58.     print(a, n);  
  59.     system("pause");  
  60.     return 0;  
  61. }  

运行  

  


算法分析

整个排序过程我们都没有进行关键字比较,不得不说,这种做法很新颖。但计数排序也是有适用范围的:它是在序列元素都是位于[0,k)之间的情况下的一种有效排序算法。排序中我们用到了一个临时数组和一个计数数组,故空间复杂度是O(n+k)。时间主要消耗在计数和回放,故时间复杂度是O(n+k)。所以当元素普遍比较小的时候,即k较小时:k=O(n),时间复杂度是O(n),这是线性的。而当k较大时,不仅时间上不划算,空间上也不划算。

0 0
原创粉丝点击