1.什么是基数排序
基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,借以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。
2.基数排序图解
3.基数排序代码实现
public static void radixSort(int[] nums) {
int len = nums.length;
int die = 10;
int dividend = 1;
Map<Integer, List<Integer>> map = new HashMap<>();
int max = 0;
do {//循环比较位数 个十百千万。。。
for (int i = 0; i < len; i++) {
if (nums[i] > max) {
max = nums[i];
}
int positionNum = nums[i] % die / dividend;
List<Integer> list = map.getOrDefault(positionNum, new ArrayList<>());
list.add(nums[i]);
map.put(positionNum, list);
}
//比较位数后 除数 跟模均乘10
die *= 10;
dividend *= 10;
//将排序的字段赋值回数组
int index = 0;
int nums_Index = 0;
while (index < 10) {
List<Integer> list = map.getOrDefault(index, new ArrayList<>());
for (Integer integer : list) {
nums[nums_Index++] = integer;
}
map.remove(index);
index++;
}
} while (dividend <= max);//当除数大于最大值后 不在继续
}
4.基数排序的效率
初看起来 ,基数排序的执行效率似乎好得让人无法相信 。所有要做的只是把原始的数据项从数 组复制到链表 ,然后再复制回去 。如果有 IO 个数据项 ,则有 20 次复制。对每一位重复这个过程 。假设对 5 位的数字排序 ,就需要 20*5,等于100 次复制。如果有100 个数据项 ,那么就有 200*5 等于 1000 次复制 。复制的次数和数据项的个数成正比 ,即 O(N) ,这是我们看到的效率最高的排序 算法 。
不幸的是 ,一般是这样 :只要数据项越多 ,就需要越长的关键字 。如果数据项增加 10 倍 ,那 么关键字就需要再增加另一位 。复制的次数是和数据项的个数与关键字的位数的乘积成正比 。位数 是关键字值的对数 ,因此在绝大多数的情况下 ,算法的执行效率倒退为 O(N*logN),和快速排序算 法相同 。
尽管从数字中提取出每一位需要花费时间 ,但是没有比较。每两次复制需要一次位提取。然而, 一台给定的计算机在二进制中的位提取操作快于比较操作 。当然,与归并排序类似 ,基数排序所需 要的存储空间是快速排序的二倍 。