/**
复杂度:nlogB(N),其中B字符集的个数(桶的数量),N为待排序数据集合中最大的值
算法流程:
1.分配:先将数据分配到某个桶bucket
2.收集:从后往前将数据放入一个临时数组。
//从后往前保证原先排在后面的依然放在下标较大的位置,从而保证了排序的稳定性
3.还原:再将临时数组的数据放回原先的数组
准备下一轮分配和收集,直到分配方式用完
*/
const int BASE=10;
int arr[5000001],temp[5000001];
void radixSort(int *a,int n)
{
int Max=a[0],exp=1;
int i,*b=temp;
for(i=1;i<n;i++)if(a[i]>Max)Max=a[i];
while(Max/exp>0)
{
int bucket[BASE]={0};
for(i=0;i<n;i++)
bucket[(a[i]/exp)%BASE]++;
for ( i = 1; i < BASE; i++)
bucket[i] += bucket[i - 1];
for(i=n-1;i>=0;i--)//稳定性
b[--bucket[(a[i]/exp)%BASE]]=a[i];
swap(a,b);
exp*=BASE;
}
for(int i=0;i<n;i++)
printf("%d ",a[i]);
putchar('\n');
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
scanf("%d",&arr[i]);
radixSort(arr,n);
}
return 0;
}