基数排序定义
基数排序(radix sort)是一种桶排序(bucket sort), 先把个位相同的数字放到同一个桶里,然后完成对个位数字大小的排序,然后再在前面的基础上对十位 上的数字进行排序,然后依次进行到最高位, 最后完成整个排序。
算法分析
对于十进制来说,每个位 总共有 0~9 10 种可能
举一个例子, 对一下数组进行排序:
[34, 62, 11, 56, 4, 73, 2, 25, 38, 65]
首先对个位进行排序(一共有0~9 10个桶):
0 |
1 | 11
2 | 2, 62
3 | 73
4 | 4, 34
5 | 25, 65
6 | 56
7 |
8 | 38
9 |
统计结果如上,然后依次从 0~9 这10个桶中按顺序取出数字后排序,排序结果为
[11,2,62,73,4,34,25,65,56,38]
然后在上面的基础上比较十位, 按照十位这个数字的大小再进行排序:
0 | 2,4
1 | 11
2 | 25
3 | 34,38
4 |
5 | 52, 56
6 | 65
7 | 73
8 |
9 |
然后依次从 0~9 这10个桶中按顺序取出数字后排序,由于最高位是10位,排序结束, 最终排序结果为:
[2, 4, 11, 25, 34, 38, 52, 56, 65, 73]
代码实现
/**
* 基数排序
* @param arr 数据
* @param d 最大位(1、、10、100、1000)
*/
public static void radixSort(int[] arr, int d) {
int length = arr.length;//数据的个数
//创建一个二维数组,用来作为桶,总有0~9 10个桶,所以一维长度为10
//最极端的可能就是所有数都装进了一个桶, 所以桶的长度为length,防止装不下
int[][] bucket = new int[10][length];
int n = 1;//刚开始从 个位 开始痛排序
while(n<d) {
int[] order = new int[10];//总共有0~9 10个数字
for (int num : arr) {
int digit = (num/n) % 10;//求余
bucket[digit][order[digit]] = num;
order[digit]++;//记录每个 位 有几个数, 如果当前正在比较个数,那么order[0] = 3 则表示个位为0的数有三个
}
int k = 0; //记录arr数组的脚标
for(int i=0; i<10; i++) {//将前一个循环生成的桶里的数据,依次取出重新排序
if(order[i] != 0) {//说明这个桶有数字
for(int j=0; j<order[i]; j++) {
arr[k] = bucket[i][j];
k++;
}
}
}
n *= 10;
}
}
测试结果
public class SortDemo {
public static void main(String[] args) {
int[] arr = randomArray(10);
radixSort(arr, 100);
System.out.println(Arrays.toString(arr));
}
/**
* 基数排序
* @param arr 数据
* @param d 最大位(1、、10、100、1000)
*/
public static void radixSort(int[] arr, int d) {
int length = arr.length;//数据的个数
//创建一个二维数组,用来作为桶,总有0~9 10个桶,所以一维长度为10
//最极端的可能就是所有数都装进了一个桶, 所以桶的长度为length,防止装不下
int[][] bucket = new int[10][length];
int n = 1;//刚开始从 个位 开始痛排序
while(n<d) {
int[] order = new int[10];//总共有0~9 10个数字
for (int num : arr) {
int digit = (num/n) % 10;//求余
bucket[digit][order[digit]] = num;
order[digit]++;//记录每个 位 有几个数, 如果当前正在比较个数,那么order[0] = 3 则表示个位为0的数有三个
}
int k = 0; //记录arr数组的脚标
for(int i=0; i<10; i++) {//将前一个循环生成的桶里的数据,依次取出重新排序
if(order[i] != 0) {//说明这个桶有数字
for(int j=0; j<order[i]; j++) {
arr[k] = bucket[i][j];
k++;
}
}
}
n *= 10;
}
}
public static int[] randomArray(int length) {
int[] arr = new int[length];
Random random = new Random();
for(int i=0; i<length; i++) {
arr[i] = random.nextInt(100);
}
//自动生成随机数组,先进行一次原始数据打印
System.out.println(Arrays.toString(arr));
return arr;
}
}
输出结果:
[34, 62, 11, 56, 4, 73, 2, 25, 38, 65]
[2, 4, 11, 25, 34, 38, 56, 62, 65, 73]