算法思想:
将每一个关键字的各位,依次进行稳定的计数排序
时间复杂度:
设数组长度为n,最大数的位数为k,进制为r,
则需要k次循环进行分配和收集,
每一次分配需要O(n),收集需要O(n),即为O(k*n)
(如果采用链式存储则每一次分配收集都需要O(n+r),即为O(k*(n+r))
空间复杂度:
需要r个桶以及n个临时数组来收集,即为O(n+r)
(如果采用链式存储则不需要临时数组,即为O(r))
稳定性: 稳定
Java代码实现(LSD最低为优先,升序,包含测试)
import java.util.Arrays;
import java.util.Random;
public class RadixSort {
public static void main(String[] args) {
checkBatch(1000, 20, 100, true);
}
/**
* 基数排序
* @param arr
*/
public static void radixSort(int[] arr) {
if (arr.length <= 1) // 极端情况处理
return;
int max = getMax(arr); // 获取最大值
for (int base = 1; max / base > 0; base *= 10) { // 以最大元素的位数进行便利
int[] bucket = new int[10];
int[] tmp = new int[arr.length];
for (int i = 0; i < arr.length; i++) { // 初始化bucket
int p = arr[i] / base % 10; // 获得当前位的值
bucket[p]++;
}
for (int i = 1; i < 10; i++) { // 得到累加后的bucket,决定该算法稳定的关键所在
bucket[i] += bucket[i - 1];
}
for (int i = arr.length - 1; i >= 0; i--) { // 收集
int p = arr[i] / base % 10;
tmp[bucket[p] - 1] = arr[i];
bucket[p]--;
}
for (int i = 0; i < arr.length; i++) { // 替换
arr[i] = tmp[i];
}
}
}
/**
* 获取数组中的最大元素
* @param arr
* @return
*/
private static int getMax(int[] arr) {
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (max < arr[i])
max = arr[i];
}
return max;
}
/**
* 打印数组的所有元素
* @param arr
*/
private static void showArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
}
/**
* 对比两个数组的所有元素是否一致
* @param arr0
* @param arr1
* @return: 是否一致
*/
private static boolean check(int[] arr0, int[] arr1) {
for (int i = 0; i < arr1.length; i++) {
if (arr0[i] != arr1[i])
return false;
}
return true;
}
/**
* 单次测试
* @param maxSize: 测试数组的最大长度
* @param maxNum: 测试数组的元素最大值
* @param show: 是否展示数组
* @return: 是否错误
*/
private static boolean checkOnce(int maxSize, int maxNum, boolean show) {
boolean bool = true;
Random rd = new Random();
int size = rd.nextInt(maxSize + 1); //0 ~ maxSize
int[] arr0 = new int[size];
int[] arr1 = new int[size];
for (int i = 0; i < arr0.length; i++) {
arr0[i] = rd.nextInt(maxNum + 1); // 0 ~ maxNum
arr1[i] = arr0[i];
}
if (show) showArray(arr0);
radixSort(arr0); // 基数排序
Arrays.sort(arr1); // 自带排序
bool = check(arr0, arr1);
if (show) {
showArray(arr0);
if (!bool) {
System.out.println("error!");
}
}
return bool;
}
/**
* 批量测试
* @param times: 测试次数
* @param maxSize: 测试数组的最大长度
* @param maxNum: 测试数组的元素最大值
* @param show: 是否展示数组
*/
private static void checkBatch(int times, int maxSize, int maxNum, boolean show) {
int error = 0;
for (int i = 0; i < times; i++) {
if (!checkOnce(maxSize, maxNum, show))
error++;
}
System.out.println("error_sum: " + error); // 统计错误次数
}
}
原文:https://www.cnblogs.com/iceix/p/13832066.html