基数排序不同于和一般常规的排序方法不一样,因为技术排序需要依赖其他排序方法,基数排序的思想就是将待排序数据拆分成多个关键字进行排序,在对关键字进行排序的时候通常有两种解决方案:
最高位优先法MSD
最低位优先法LSD
也许这样说比较抽象,可以看一个例子
181,253,12,24
这个数据最大位数是百位,那就拆分成三个关键字,然后进行比较,第一轮
比较个位,4是最大,3第二,于是得出
181,12,253,24
第二轮,比较十位,8最大
12,24,253,181,
最后一轮,比较百位
12,24,181,253
理论流程大概就是这样,十分简单,对于拆分比较的话,有一个最快的排序方式,那就是采用桶式排序,因为我们知道了范围,拆分之后就是0到9,能够很轻易的进行排序,效率也很高,这个时候就体现了桶式排序的作用,这也是最优组合,当然你也可以用其他排序,只是相对比较难一点而已。
代码如下
package com.demo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
/**
* Created by wk on 2014/7/1.
*/
public class MultiKeyRadixSort {
//基数排序
public static void main(String args[]) {
int[] older_arr = getArray(10);
System.out.println("未排序:");
display(older_arr);
int[] new_arr = radixSort(older_arr,10,4);
System.out.println("排序后:");
display(new_arr);
}
public static void display(int[] arrays) {
for (Integer i : arrays)
System.out.print(i + ",");
}
//获取不重复随机数
public static int[] getArray(int n) {
List<Integer> list = new ArrayList<Integer>();
int[] ins = new int[n];
for (int i = 0; i < n; i++) {
int number = new Random().nextInt(1000);
if (!list.contains(number)) {
list.add(number);
ins[i] = number;
}
}
return ins;
}
public static int[] radixSort(int[] sorts,int radix,int d) {
int arrayLength = sorts.length;
int[] tmp = new int[arrayLength];
int[] buckets = new int[radix];
//依次从最高位的子关键字对待排数据进行排序
//下面循环中rate用户保存当前计算的位
for (int i = 0, rate = 1; i < d; i++) {
//重置count数组
Arrays.fill(buckets, 0);
//将数组的元素复制到tmp数组中进行缓存
System.arraycopy(sorts, 0, tmp, 0, arrayLength);
//计算每个待排序数据的子关键字
for (int m = arrayLength - 1; m >= 0; m--) {
int subKey = (tmp[m] / rate) % radix;
buckets[subKey]++;
}
for (int j = 1; j < radix; j++) {
buckets[j] = buckets[j] + buckets[j - 1];
}
//按子关键字对指定数据进行排序
for (int m = arrayLength - 1; m >= 0; m--) {
int subKey = (tmp[m] / rate) % radix;
sorts[--buckets[subKey]] = tmp[m];
}
rate *= radix;
}
return sorts;
}
}