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