基数排序将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零. 然后,从最低位开始, 依次进行一次排序.这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列.基数排序的方式可以采用LSD(Least significant digital)或MSD(Most significant digital),LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始,LSD适应与那些位数较少的数字进行排序,而对于位数较多的数选择MSD效果要好,下面这个例子我是选用的LSD的排序方式
package com.lamp.sort;
import java.util.Arrays;
public class RadixSortTest {
public static void main(String[] args) {
int[] data = { 5, 20, 4, 15, 11};
printArray(data);
System.out.println("\r" + "升序排序后-------");
//数组中最多位数为2,设定基数为10进行排序
sortArrayAsc(data, 10, 2);
printArray(data);
//System.out.println("\r" + "降序排序后-------");
//数组中最多位数为2,设定基数为10进行排序
//sortArrayDesc(data, 10, 2);
//printArray(data);
}
//升幂排序
private static void sortArrayAsc(int[] data, int radix, int d) {
//定义一个临时数组大小和data数组相等
int[] temp = new int[data.length];
//定义一个位计数器,用来存放当前位的元素有多少个
int[] bucket = new int[radix];
int rate = 1;
for (int i = 0; i < d; i++) {
//将data数组中的各个元素复制到temp数组中
System.arraycopy(data, 0, temp, 0, data.length);
//将bucket数组的各个元素重置0
Arrays.fill(bucket, 0);
//当i等于0时,原数组为5, 20, 4, 15, 11,个位数的值分别为5,0,4,5,1
//此时bucket数组的值为1,1,0,,0,1,2,0,0,0,0即个位数为0,1,4的数各一个,个位数为5
//的数有两个,并将较大的数置于较后
for (int j = 0; j < data.length; j++) {
int index = (temp[j] / rate) % radix;
bucket[index] += 1;
}
//统计各元素出现位置,拿原数组来说,个位数为0的数出现了一次,位置为1,个位数为1的数也出现了
//一次,此时它的实际位置应该为自身出现个数与0出现个数之和,其余元素位置同理
//经过循环后的bucket数组为1,2,2,2,3,5,5,5,5,5
for (int j = 1; j < bucket.length; j++) {
bucket[j] = bucket[j] + bucket[j - 1];
}
for (int j = data.length - 1; j >= 0; j--) {
//当j等于data.length时,即j=4时,temp[4]=11,index的值为1,由于数组下标值比元素位置小1
//data[--2]=11,即data[1]=11,bucket[index]值减1(由于此位对应的元素已经有一个拍好了顺序)
int index = (temp[j] / rate) % radix;
data[--bucket[index]] = temp[j];
}
//一次循环过后我们可以看到data数组变为20,11,4,5,15,我们可以看到个位数字较大的数排到了较后
//接着rate乘以10并对十位进行相应排序
rate *= radix;
}
}
private static void sortArrayDesc(int[] data, int radix, int d) {
int[] temp = new int[data.length];
int[] bucket = new int[radix];
int rate = 1;
for (int i = 0; i < d; i++) {
System.arraycopy(data, 0, temp, 0, data.length);
Arrays.fill(bucket, 0);
for (int j = 0; j < data.length; j++) {
int index = (temp[j] / rate) % radix;
//降序排序最大的特点就是将位数较大的元素出现次数放在了前面
bucket[9 - index] += 1;
}
for (int j = 1; j < bucket.length; j++) {
bucket[j] = bucket[j] + bucket[j - 1];
}
for (int j = data.length - 1; j >= 0; j--) {
int index = (temp[j] / rate) % radix;
data[--bucket[9 - index]] = temp[j];
}
rate *= radix;
}
}
private static void printArray(int[] data) {
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + " ");
}
}
}