线性时间的桶排序介绍与理解(含c源代码)

来源:互联网 发布:三家运营商的网络制式 编辑:程序博客网 时间:2024/05/18 03:32

桶排序的介绍它的思想就是把区间分成均匀的大小相同的子区间(也称为桶);比如将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;

程序源代码如下:

#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");}}


 运行结果:

    随机生成的100个数:

   随机生成的100个数:范围0~100


总结:

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

0 0