线性时间选择c语言,线性时间的桶排序算法的介绍与理解(c语言)

桶排序的介绍:它的思想就是把区间分成均匀的大小相同的子区间(也称为桶);比如将100以内的数排序,就可以分成10个区间(桶);第一个1-10,第二个11-20;第三个21-30;.......第十个91-100;所取得的数放到对应的桶中,如果一个桶出现相同的,并要对它进行正确的处理;

编程思维:利用上一章节的基数排序,我们可以利用数组的下标从而按照个,十,百的相应位数进行排序,而数组下标与基数排序就能够很好的衔接起来;比如

134,321;利用数组arr[i][j]进行第一次个位分别为4,1存取就会是134存到arr[4][1];321存到arr[1][1];依次进行下去;进行第二次十位分别为3,2存取就会是134存到arr[3][1];321存到arr[2][1];进行第三次百位分别为1,3存取就会是134存到arr[1][2];321存到arr[3][2];特别注意,j的数出现依次就会加1;

a4c26d1e5885305701be709a3d33442f.png

程序源代码如下:

#include< stdio.h>

#include< stdlib.h>

#include< math.h>

#define MAX

100 //生成的数的个数定义;

void bucket_sort(unsigned

*,int); //桶排序函数的原型

void print(unsigned

*,int); //打印函数的原型int main()

{

unsigned array[MAX];

int i=0;

//为数组元素随机赋值for(i=0;i<

MAX;++i)

array[i]=rand(); //随机生成数;如果你想设置生成数的范围,如100范围内rand()0

printf("排序前的顺序:\n");

print(array,MAX);

//排序

bucket_sort(array,MAX);

printf("排序后的顺序:\n");

print(array,MAX);

return 0;

}

void bucket_sort(unsigned * arr,int len)

{

unsigned

*buckets[10]; //指针数组,也就是二维数组;unsigned

b=0,n; //用于取整数各位上的值;b为指数n为1,10,100...;

int

index; //数组下标计数索引int

indexs[10]; //各个桶下标计数索引

int i,j;

//分配动态内存作为桶for(i=0;i<

10;++i)

buckets[i]=(unsigned *)malloc(sizeof(unsigned)*len);

while(1)

{

//计数索引清零

index=0;

for(i=0;i< 10;++i)

indexs[i]=0;

//数组至桶,同时利用数组的特性运用到了基数排序;

for(i=0;i< len;++i)

{ n=pow(10,b);

buckets[arr[i]/n][indexs[arr[i]/n]++]=arr[i];

//printf("#%d,",indexs[arr[i]/n]);

}

//桶至数组

for(i=0;i< 10;++i)

for(j=0;j< indexs[i];++j)

arr[index++]=buckets[i][j];

//为取元素的下一位做准备

b++;

//判断是否该结束

for(i=0;arr[i]< n&&i< len;++i);

if(i==len) break;

}

//释放动态内存

for(i=0;i< 10;++i)

free(buckets[i]);

}

void print(unsigned * arr,int len)

{

int i=0;

for(i=0;i< len;++i)

{

printf("m",arr[i]);

//10个元素一行

if((i+1)==0)

printf("\n");

}

}

//总结:线性时间排序中的计数,基数,桶排序;相互之间都存在一种关系,有数组就能够很好地衔接起来;计数对于大的数开辟的空间过于浪费;它的原理是一一对应的;基数排序则是通过从右到左,从个位,十位,百位..进行排序,对于计数排序而言,具有比较大的优势,空间节省;桶排序利用了均匀分布的思想,空间和时间复杂度相比前面都有很大的优势!!很经典的语句:buckets[arr[i]/n][indexs[arr[i]/n]++]=arr[i];

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值