7.计数排序
特点:计数排序是非比较排序算法,就是该算法不需要进行比较,所以时间复杂度为O(n+k),该算法速度非常快,是典型的使用空间换取时间的排序算法。
基本过程:就是把一串数字全部变成另外一个数组的下标,由于下标是有序顺序,再把数字通过下标的形式还原出来,那就是一串有序的序列。
实现具体步骤,把数字变成下标很简单,但是怎么记录这个下标所指的数字是该序列中的数字呢?
所以我们需要一个可以记录该数字是否是原序列中数字的状态变量,在编程语言中,记录俩个状态变量的方法有俩种,一种是0和1,另外一种是使用true和false(本质上还是true和false),如果该数字是原序列里面的数字,那么该数字的状态就是1,否则就是0(如果你喜欢也可以使用别的变量来表示),那么接下来就是具体代码的实现了
int maxs(int a[max]){//取最大值
int maxs=a[0];
int i;
for(i=0;i<max;i++){
if(maxs<=a[i]){
maxs=a[i];
}
}
return maxs;
}
void countsort(int a[max]){//开始计数排序 //8
int len=maxs(a);
// int b[len+1]={0};//b下标是a中的值
int *b=(int*)malloc(sizeof(int)*(len+1));
int i;
int current=0;
for(i=0;i<len+1;i++){//初始化b
b[i]=0;
}
for(i=0;i<max;i++){//b下标中值++
b[a[i]]++;
}
for(i=0;i<len+1;i++){//把a中的值进行排序
while(b[i]>0){
a[current]=i;
b[i]--;
current++;
}
}
}
里面有一个转折点:
那就是一串数字把数字转变成下标如果想要把所有的数字都变成下标存储起来,如何才能把数字变成下标存储起来呢?
有一个办法,那就是取出序列里面的最大值,建立一个数组,数组的最大范围就是这个最大值(如果你愿意这个最大值可以+1,按照正常的人的思想)
接下来就是依次读取原数组的值,把值变成下标++,如果新数组的值是1,说明这个数出现一次,是2出现俩次,以此类推...
通过新建数组中的里面的值把原数组重新赋值
核心代码:
for(i=0;i<len+1;i++){//把a中的值进行排序
while(b[i]>0){
a[current]=i;
b[i]--;
current++;
}
}
这样,最终原数组中的值就是有序的!
缺点:
如果数字数量很小,但是数字之间的差值很大,比如俩个数字【1,100】,通过计数排序,需要建立一个大小为101的数组,这样很浪费空间,所以该排序有时候很浪费空间!使用空间换取时间的排序算法。
如果喜欢的记得点一个关注哟!