//桶排序
//原理:要对数组a[n]进行排序,新建一个b[9][n-1]的二维数组,
//把a中的元素分别放到数组b中,原则为:
//1.根据a中元素个位数的数字放到b中相应的行,如3则放到b中的第三行,100放到第0行
//此过程称为分布,用分布函数distributeElments()实现
//2.将b中的元素按照顺序复制回a中,此过程称为回收,用回收函数collectElments()实现
//3.然后依次按照a中元素的十位,百位...重复上述过程.其中如3的十位为0,放入b中的0行中
//用函数numOfDigits()求得a中最大数的位数.

#include<iostream.h>

int a[]={1,255,8,6,25,47,14,35,58,75,96,158,657};
const int len=sizeof(a)/sizeof(int)-1;
int b[9][len]={0};//将b全部置0

void bucketSort(int a[]); //桶排序函数
void distributeElments(int a[],int b[9][len],int digits);
void collectElments(int a[], int b[9][len]);
int numOfDigits(int a[]);
void zeroBucket(int b[9][len]); //将b数组中的全部元素置0

void main()
{

cout<<"原始数组:";
for(int i=0; i<len; i++)
cout<<a[i]<<",";
cout<<endl;

bucketSort(a);

cout<<"排序后数组:";
for(i=0; i<len; i++)
cout<<a[i]<<",";
cout<<endl;
}

void bucketSort(int a[])
{
int digits=numOfDigits(a);

for(int i=1; i<=digits; i++)
{
distributeElments(a,b,i);
collectElments(a,b);

if(i!=digits)
zeroBucket(b);
}
}


int numOfDigits(int a[])
{
int largest=0;
for(int i=0; i<len; i++) //获取最大值
{
if(a[i]>largest)
largest=a[i];
}

int digits=0; //digits为最大值的位数

while(largest)
{
digits++;
largest/=10;
}

return digits;

}

void distributeElments(int a[],int b[9][len],int digits)
{
int divisor=10; //除数

for(int i=1; i<digits; i++)
divisor*=10;

for(int j=0; j<len; j++)
{
int numOfDigist=(a[j]%divisor-a[j]%(divisor/10))/(divisor/10);
//numOfDigits为相应的(divisor/10)位的值,如当divisor=10时,求的是个位数
int num=++b[numOfDigist][0];//用b中第一列的元素来储存每行中元素的个数
b[numOfDigist][num]=a[j];
}
}

void collectElments(int a[], int b[9][len])
{
int k=0;
for(int i=0; i<=9; i++)
for(int j=1; j<=b[i][0]; j++)
{
a[k++]=b[i][j];
}
}

void zeroBucket(int b[][len])
{
for(int i=0; i<9; i++)
for(int j=0; j<len; j++)
b[i][j]=0;
}