排序思路:
本文采用LSD(Least significant digital)排序方式,基数取10。
对于给定数组,先按照个位进行排序,再按照十位进行排序,再按照百位进行排序……没有该位的,排序时按0处理。
桶子思想:我们定义“分别选取个位、十位、百位…等进行元素比较”为一轮。每一轮排序过程,我们准备10个清空的桶子,按照0-9的顺序编号,将该位是对应编号的元素,放入对应的“木桶”中(每个桶中正常放入元素即可,不用在乎顺序);归类放置完毕后,从0号桶开始,逐个拿出里面的元素(顺序无所谓),按序(拿出先后)覆盖原给定数组。覆盖完成后,本轮结束。当比较完所有位后,排序结束。
整个过程,桶子会协助排序,这样随着比较位的变化,排序会自然完成。
举例:
{22,35,16,9,5,20}
1)找出最高比较位
最大值是35,其最高位是十位
2)按照个位进行排序
计算个位:
lsd=2 lsd=5 lsd=6 lsd=9 lsd=5 lsd=0
分别放入桶子:
0:20
1:
2:22
3:
4:
5:35,5
6:16
7:
8:
9:9
然后挨个拿出,覆盖原数组:
{20,22,35,5,16,9}
3)按照十位进行排序,同理进行“归桶”
0:5,9
1:16
2:20,22
3:25
4:
5:
6:
7:
8:
9:
然后挨个拿出,覆盖原数组:
{5,9,16,20,22,35}
4)已经排完最高位,排序结束。
c实现:
void radixSort(int array[], int len){
int tmp[10][len] = {0}; //桶子:储存余数分别为0-9的元素
int bucket[10] = {0}; //储存余数分别为0-9的元素个数,用于判断该桶子中是否有数。
int max_val=0;
int exp=1;
int exp_max=1;
int i=0;
//求可能的最高位(万、千、百)exp_max
for(i=0; i<len; i++){
if(array[i]>max_val)
max_val = array[i];
}
while(max_val>=10){
max_val /= 10;
exp_max *= 10;
}
while(exp<=exp_max) {
//每次使用桶子前必须要清空
memset(tmp, 0, sizeof(tmp));
memset(bucket, 0, sizeof(bucket));
for (i = 0; i < len; i++) {
int lsd = (array[i] / exp) % 10; //当前元素求余数
tmp[lsd][bucket[lsd]++] = array[i]; //当前元素求余数
}
int k = 0;
for (i = 0; i < 10; i++)
if (bucket[i] > 0) { //若该余数桶中有数
for (int j = 0; j < bucket[i]; j++) {
array[k++] = tmp[i][j]; //按序放入array
}
}
exp *= 10;
}
}
时间复杂度为:O(Kn),K与最高位有关,n为数组长度。