基数排序是一种稳定排序所以每一次排序并不会破坏原有的同级大小关系
所以可以对每一位数分别排序最后将整个数组有序
int maxbit(int data[], int n) //辅助函数,求数据的最大位数
{
int maxData = data[0]; ///< 最大数
/// 先求出最大数,再求其位数,这样有原先依次每个数判断其位数,稍微优化点。
for (int i = 1; i < n; ++i)
{
if (maxData < data[i])
maxData = data[i];
}
int d = 1;
int p = 10;
while (maxData >= p)
{
maxData /= 10;
++d;
}
return d;
}
void radixsort(int data[], int n) //基数排序
{
int d = maxbit(data, n);
int *tmp = new int[n];
int *count = new int[10]; //计数器
int i, j, k;
int radix = 1;
for(i = 1; i <= d; i++) //进行d次排序
{
for(j = 0; j < 10; j++)
count[j] = 0; //每次分配前清空计数器
for(j = 0; j < n; j++)
{
k = (data[j] / radix) % 10; //统计每个桶中的记录数
count[k]++;
}
for(j = 1; j < 10; j++)
count[j] = count[j - 1] + count[j]; //将tmp中的位置依次分配给每个桶,用于后续分配每个数的位置,加起来后每个桶的数量减一就是他在数组中的下标
for(j = n - 1; j >= 0; j--) //将所有桶中记录依次收集到tmp中
{//从后面倒着赋值是为了维持稳定性,同级的数原本是什么位置依然不变
k = (data[j] / radix) % 10;
tmp[count[k] - 1] = data[j];//因为count统计的是数量所以存到数组里的下标要用数量减一
count[k]--;
}
for(j = 0; j < n; j++) //将临时数组的内容复制到data中
data[j] = tmp[j];
radix = radix * 10;//从最小位开始每一位排序
}
delete []tmp;
delete []count;
}