接下来的博文还会介绍一些好玩的排序算法,比如:桶排序,堆排序,鸡尾酒排序,猴子排序(随机排序),地精排序(据说最简单的排序算法)等等!
今天先说计数排序:这是一种时间复杂度为O(n)的排序方法。虽说时间复杂度是最低的排序方法,但是它的缺点也是显而易见的。接着往下看,你就会明白了。
原理:给定一定数量的无序的数据,存在数组a中,可以通过遍历一遍数据得到这些数据的范围是(m,n)。新建立一个与原数据个数相同的数组b(初始化为全零),然后再遍历一遍数组a时,执行b[a[index]]++。当遍历完成时,就可以通过遍历数组b输出排序后的结果(b数组中的数据表示的是对应位置数据出现的次数)。
上面的说明是基于m大于零的情况,如果m<0,原理相同,代码改动很小,相信小伙伴们已经想到了吧!就是让index= b[a[index]-m]++。
如果上边的解释你还没弄明白的话,没事下面用图再来说明一下。预先通过遍历获得数组的大小范围。
优缺点:从上图可以看出,该算法原理简单,效率很高。如果是对小数据量排序来说,完全可以,但是如果要排序的数据量很大多达几百万个,就要同时开辟两块这么大的内存浪费空间。此外该算法只是针对×××数据合适,如果我要排序的数据中存在浮点数据,就会失效。因此实际中这种排序算法用的很少!
代码实现也很简单:下面代码可以适应于m>=0和m<0的情况。
#include<stdio.h>
#include<stdlib.h>
#define NUM 10
intsort_data[NUM];
voidcount_sort(int *data,int num,int *count,int min_num);
int main(void)
{
int i,j;
int max_num,min_num;
int range;
int *count_data;
for(i=0;i<NUM;i++)
{
sort_data[i]=rand();
}
max_num=sort_data[0];
min_num=sort_data[0];
for(i=1;i<NUM;i++)//寻找数组的最大值和最小值
{
if(max_num<sort_data[i])
{
max_num=sort_data[i];
}
if(min_num>sort_data[i])
{
min_num=sort_data[i];
}
}
range=max_num-min_num+1;//确定数据范围并开辟相应大小的内存
count_data=(int*)calloc(range,sizeof(int));
count_sort(sort_data,NUM,count_data,min_num);//计数排序
for(i=0;i<range;i++)//显示排序的结果
{
if(0==count_data[i])
continue;
for(j=1;j<=count_data[i];j++)
printf("%d\n",i+min_num);
}
free(count_data);
count_data=NULL;
return 0;
}
voidcount_sort(int *data,int num,int *count,int min_num)
{
int i;
if(num<1)
return;
for(i=0;i<num;i++)
{
count[data[i]-min_num]++;
}
}
程序运行结果如下: