一、基数排序
基本思想:将一个序列先按个位数大小排序,再按十位数大小进行排序,依次直到最大值的最大位数。
说明:
(1)基数排序是对传统桶排序的扩展,速度很快
(2)基数排序是经典的空间换时间的算法,占用内存很大,当对海量数据进行排序时,容易造成OutOfMemoryError
(3)基数排序是稳定的
相关术语解释:
(1)稳定:如果a原本在b前面,而a=b,排序之后a仍在b的前面
(2)不稳定:如果a原本在b前面,而a=b,排序之后a可能会出现在b的后面
(3)内排序:所有排序操作都在内存中完成
(4)外排序:由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行
(5)时间复杂度:一个算法执行所耗费的时间
(6)空间复杂度:运行完一个程序所需的内存大小
(7)n:数据规模
(8)In-place:不占用额外内存
(9)Out-place:占用额外内存
代码实现:
public static void radixsort(int[] arr) {
//1.找到最大的数的位数
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
int maxlength = (max + "").length();//把最大数转化为字符串,调用其length方法获得最大位
//2.进行排序,总共进行maxlength轮排序
for (int i = 1,n = 1; i < maxlength; i++,n*=10) {
int[][] bucket = new int[10][arr.length];
int[] bucketElementCounts = new int[10];
//3.进行对应轮的各元素遍历排序
for (int j = 0; j < arr.length; j++) {
int digitOfElement = arr[j] / n % 10;//取模
bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];
bucketElementCounts[digitOfElement]++;
}
4.把各桶中的数依次放回原数组
int index = 0;
for (int k = 0; k < bucketElementCounts.length; k++) {
if (bucketElementCounts[k] != 0) {
for (int l = 0; l < bucketElementCounts[k]; l++) {
arr[index] = bucket[k][l];
index++;
}
bucketElementCounts[k] = 0;
}
}
System.out.println("第" + i + "轮排序后的结果:" + Arrays.toString(arr));
}
}