基数排序
本文最后更新于:2022年12月13日 晚上
基数排序
基本介绍
- 基数排序(Radix Sort)属于“分配式排序” (distribution sort),又称“桶子法”(bucket sort)或 bin sort,顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用。
- 基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法。
- 基数排序(Radix Sort)是桶排序的扩展。
- 基数排序是1887年赫尔曼·何乐礼发明的。它是这样实现的:将整数按位数切割成不同的数字,然后按每个位数分别比较。
基本思想
将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。
代码实现
// 基数排序
public static void radixSort(int[] arr) {
// 二维数组存放数据
int[][] bucket = new int[10][arr.length];
// 记录每个桶里有多少个数
int[] bucketElementCounts = new int[10];
int max = 0;
// 确定最大值
for (int item : arr) {
if (item > max) {
max = item;
}
}
max = (max + "").length();
for (int j = 0, num = 1; j < max; j++, num *= 10) {
for (int value : arr) {
int digitOfElement = (value / num) % 10;
// 另外一种,速度较慢
// int digitOfElement = (arr[i] % (num * 10)) / num;
// 放入对应的桶
bucket[digitOfElement][bucketElementCounts[digitOfElement]] = value;
bucketElementCounts[digitOfElement]++;
}
// 按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组)
int index = 0;
for (int k = 0; k < bucketElementCounts.length; k++) {
if (bucketElementCounts[k] > 0) {
for (int n = 0; n < bucketElementCounts[k]; n++) {
arr[index] = bucket[k][n];
index++;
}
bucketElementCounts[k] = 0;
}
}
}
}
特点总结
- 基数排序是对传统桶排序的扩展,速度很快。
- 基数排序是经典的空间换时间的方式,占用内存很大,当对海量数据排序时容易造成
OutOfMemoryError
。 - 基数排序时稳定的。(注:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,
r[i]=r[j]
,且r[i]
在r[j]
之前,而在排序后的序列中,r[i]
仍在r[j]
之前,则称这种排序算法是稳定的;否则称为不稳定的。) - 基数排序不适用有负数的数组。