排序算法:简易桶排序、冒泡排序、快速排序
简易桶排序
桶排序大致意思就是将数组中的每一个元素都看做一个桶,每出现一个数就在对应编号的桶中放一个标记,最后只需要统计每个桶中有几个标记,然后遍历数组将数组中的元素按顺序输出就可以了。
上图中定义了11个桶是应为需要排序的数都在0-10的范围内,总共有11个数,而如果要对0-1000范围内的数进行排序,就需要定义1001个桶,来表示0~1000之间每个数出现的次数,这里的桶的作用其实就是“标记”每个数出现的次数。
案例:要给五个同学进行按分数排名,分数分别为5分、3分、5分、2分、8分(总分10分),
因为分数在0~10之间,因此需要先定义一个长度为11的数组,刚开始时,先将数组中所有元素的初始值赋值为0,表示这些分数都没有出现过,例如a[0]等于0表示目前没有人得0分,同理a[1]等于0表示目前没有人得1分…依此类推。
然后开始处理每个人得分数,第一个人的分数为5,就将对应的a[5]的值在原来的基础上+1,将a[5]的值从0改为1,表示5出现过一次了。
第二个人的分数是3,因此就将a[3]的值在原来基础上+1,将a[3]的值从0改为1,表示3分出现过一次了。
第三个人的分数为5分,因为5分已经出现过一次了,因此就将a[5]的值在1的基础上再加1,表示出现过两次.
综上所述,五个人的分数处理完毕后结果如下图
其实a[0]-a[10]的值就是每个分数出现的次数,因此,每个元素的值是多少就将该元素打印几次,代码入下
#include <stdio.h>
int main()
{
int a[11];
int i,j;
int n,num;
for(i = 0;i<=10;i++) //将数组中所有元素的值初始化为0
a[i]=0;
scanf("%d",&n);
for(i = 0;i<n;i++){
scanf("%d",&num);
a[num]++; //将对应元素的值在原来的基础上加1
}
for(i = 0;i<=10;i++){ //依此判断a[0]-a[10]的值
for(j = 1;j<=a[i];j++){ //值是多少就打印几次
printf("%d ",i);
}
}
return 0;
}
代码第八行循环了m次(m为桶的个数),第11行循环了n次,第15和16行一共循环了m+n次,一共循环了m+n+m+n次,桶排序的时间复杂度为O(m+n+m+n),在说时间复杂度时可以忽略较小常数,因此时间复杂度可以表示为O(m+n)次,时间复杂度较低,但是桶排序很浪费空间,如果数组元素中存在210000,就需要定义210001个桶。