桶+计数排序
int maxBit(int* a, int len) {//计算最大位数
int max = a[0],bit=1;
for (int i = 1; i < len; i++) max = max > a[i] ? max : a[i];
for (int i = max; i >= 10; i /= 10)bit++;
return bit;
}
void radixSort(int* a, int len) {
int bit = maxBit(a, len), k, radix = 1, bucket[10] = { 0 };
int* temp = new int[len];
for (int i = 1; i <= bit; i++) {//分别按个位,十位,百位。。进行排序
for (int j = 0; j < 10; j++)bucket[j] = 0;//先清0
for (int j = 0; j < len; j++) {
k = a[j] / radix % 10;//“尾数”
bucket[k]++;//记录“尾数”0-9出现次数
}
for (int j = 1; j < 10; j++)bucket[j] += bucket[j - 1];//计算填入位置//升序
//for (int j = 8; j >= 0; j--)bucket[j] += bucket[j + 1];//降序
for (int j = len - 1; j >= 0; j--) {//对于递增序列,越高位记录的数值越大,0到len-1对应尾数0到9,进行十位比较时应该让个位数大的先出去参与比较,FIFO
k = a[j] / radix % 10;//“尾数”
temp[bucket[k] - 1] = a[j];//数组下标从0开始,要减1
bucket[k]--;//下一次要放入前一个位置
}
for (int j = 0; j < len; j++)a[j] = temp[j];//排序结果记入a中
radix *= 10;//按下一个数位排序
}
delete[] temp;
}
void test02() {
//sizeof(a) / sizeof(*a)
int a3[] = { 49,38,65,97,76,13,27,49 };
int a5[] = { 15,1,2,3,5,8,4,9,6,7 };
int a2[] = { 1,2,3,4,5,7,8,9,10,6 };
int a4[] = { 1,2,3,4,5,7,8,9,10,6 };
int a6[] = { 8,3,6,4,2,1,5,7,9,10,12,11 };
int a7[] = { 16,9,20,15,3,18,13,2,17,10,5,7,11,12,6,1,19,4,8,14 };
int a8[] = { 53,17,78,9,45,65,87,32 };
int a[] = { 53, 3, 542, 748, 14, 214, 154, 63, 616 };
radixSort(a, sizeof(a) / sizeof(*a));
for (const int i : a)cout << i << ' '; cout << endl;
}
结合图来说明。第一轮,按个位排序,a中有个尾数为0的元素,1个尾数为2的元素,3个尾数为3 的元素,则尾数为2的元素放在第1位,尾数为3的元素放在第2,3,4位,这就对应了temp[bucket[k] - 1] = a[j] 和 bucket[k]--的规则。此时“桶”记录的是元素填入的位置。最后一列的tmp就是所有元素按个位排好序的结果,然后更新到原数组a中,再开始下一轮,按十位大小进行排序