Java基础排序算法(7)——基数排序
1.基数排序简述
1.1 基数排序的先决条件
- 需要排序的数组的元素均为正整数
(当然也可以变通:负数单独拿出来当作正整数排序,小数则所有元素都乘10的倍数使其全部为整数,这些拓展本文不赘述,本文例子为正整数数组排序)
- 数为短的前面补上0,比如{9,10,88,7}->{09,10,88,07}(当然用代码则使用除10取整即可,这里填上0只是为了后面图示好表达意图)
1.2 基数排序的基本步骤
-
首先保证需要排序的数组满足上述两个先决条件
-
从最低位开始,依次进行一次排序(个位,十位,百位,千位,万位…)。
举个例子:
从最低位一直到最高位排序完成以后, 数列就变成一个有序序列。
1.3 图示举例此过程
2.基数排序代码实现
package Algorithm.Sort;
import java.util.ArrayList;
/**
* 排序(7)
* 基数排序
*/
public class RadixSort extends Template {
/**
* 排序函数
*
* @param array 需排序数组
*/
public static void sort(int[] array) {
//1.计算最大数的位数;
// 找出最大数max -> 除10取整,非0则位数加1
int maxDigit = 0;//最大数的位数
int max = array[0];
for (int num : array) {
max = Math.max(max, num);
}
System.out.println("最大数" + max);
while (max != 0) {
max /= 10;
maxDigit++;
}
System.out.println("因此最大位数" + maxDigit);
//2.排序
int multiple = 1; //每次遍历需要除的10的倍数 1,10,100,1000...
int digit = 1; //排序所依据的位数 (个位,十位,百位,千位,万位....)。
int[][] temp = new int[10][array.length]; //数组的第一维表示可能的余数0-9
int[] order = new int[10]; //数组order[i]用来表示该位是i的数的个数
while (digit <= maxDigit) {
int index = 0; //数组下标,重新排列数组元素
for (int i = 0; i < array.length; i++) {
int lsd = ((array[i] / multiple) % 10);//lsd:当前位的值
temp[lsd][order[lsd]] = array[i];
order[lsd]++;//该位是lsd的数的个数+1
}
for (int i = 0; i < 10; i++) {
if (order[i] != 0)
for (int j = 0; j < order[i]; j++) {
array[index] = temp[i][j];
index++;
}
order[i] = 0;
}
multiple *= 10;//倍数*10 下次按照到下一位排序了
//输出本次排序的结果
System.out.print("按照第" + digit + "位,本轮排序结果:");
show(array);
digit++;//当前所排序的位数+1 下次按照到下一位排序了
}
}
public static void main(String[] args) {
int[] a = {12, 9, 11, 90, 118, 1, 30, 89, 65, 77, 39, 56};
System.out.println("基数排序前");
show(a);
sort(a);
assert isSorted(a);
System.out.println("基数排序后");
show(a);
}
}
3.运行效果
基数排序前
12 9 11 90 118 1 30 89 65 77 39 56
最大数118
因此最大位数3
按照第1位,本轮排序结果:90 30 11 1 12 65 56 77 118 9 89 39
按照第2位,本轮排序结果:1 9 11 12 118 30 39 56 65 77 89 90
按照第3位,本轮排序结果:1 9 11 12 30 39 56 65 77 89 90 118
基数排序后
1 9 11 12 30 39 56 65 77 89 90 118