基数排序
可以说这是排序算法中比较容易理解和书写的一个算法.稳定性较高. 所谓稳定性指的不是指排序时间稳定在一个很快或者很慢的时间.
排序的逻辑如下图
?
?因为最大的数字是三位数,所以再进行第三次排序之后(图中省略),再放回数组,就得到了有序的数组
整体代码
import java.util.Arrays;
import java.util.Random;
public class RadixSort {
public static void main(String[] args) {
// int[] arr = {81,143,99,473,512,66};
// radixSort(arr);
// System.out.println(Arrays.toString(arr));
int[] arr1 = new int[80000];
Random random = new Random();
for (int i = 0; i < arr1.length; i++) {
arr1[i] = random.nextInt(80000);
}
long start = System.currentTimeMillis();
radixSort(arr1);
long end = System.currentTimeMillis();
System.out.println("用时:"+(end - start));
System.out.println(Arrays.toString(arr1));
}
public static void radixSort(int[] arr){
int[][] bucket;
int[] index;
int last;
//获取数组中的最大值
int max = Arrays.stream(arr).max().getAsInt();
//最大值的位数
for (int x = 0 ; x < String.valueOf(max).length(); x++) {
bucket = new int[10][arr.length];
index = new int[10];
for (int i : arr) {
//获取x位数
//规律
//i % 10 ==> (i % 10 ^ 1) / 10 ^ 0
//(i % 100) / 10 ==> (i % 10 ^ 2) / 10 ^ 1
//(i % 1000) / 100 ==> (i % 10 ^ 3) / 10 ^ 2
//但是有一个需要注意的,java中的^不是幂运算,我们需要用到Math函数中的方法表示出通项公式
last = (i % (int)Math.pow(10,x+1)) / (int)(Math.pow(10,x));
//将i赋值给 第last桶的目前index指向的位置
bucket[last][index[last]++] = i;
}
//将数字依次取出
int tmp = 0;
for (int i = 0; i < bucket.length; i++) {
for (int j = 0; j < index[i]; j++) {
arr[tmp++] = bucket[i][j];
}
}
}
}
public static void radixSort_learn(int[] arr){
//既然是基于桶排序,我们先创建一个二维数组bucket[10(桶数)][arr.lenth(桶的容量)]
//因为一共10个桶,每个桶最多放arr个数,所以↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
int[][] bucket = new int[10][arr.length];
//对于每个桶,我们都需要一个指针表明它存放到哪个位置了,所以创建index[10]
int[] index = new int[10];
//第一次
for (int i : arr) {
//获取个位数
int last = i % 10;
//将i赋值给 第last桶的目前index指向的位置
bucket[last][index[last]++] = i;
}
//将数字依次取出
int tmp = 0;
for (int i = 0; i < bucket.length; i++) {
for (int j = 0; j < index[i]; j++) {
arr[tmp++] = bucket[i][j];
}
}
//[81, 512, 143, 473, 66, 99]
//第二次
bucket = new int[10][arr.length];
index = new int[10];
for (int i : arr) {
//获取十位数
int last = (i % 100) / 10;
//将i赋值给 第last桶的目前index指向的位置
bucket[last][index[last]++] = i;
}
//将数字依次取出
tmp = 0;
for (int i = 0; i < bucket.length; i++) {
for (int j = 0; j < index[i]; j++) {
arr[tmp++] = bucket[i][j];
}
}
//[512, 143, 66, 473, 81, 99]
//第三次
bucket = new int[10][arr.length];
index = new int[10];
for (int i : arr) {
//获取百位数
int last = (i % 1000) / 100;
//将i赋值给 第last桶的目前index指向的位置
bucket[last][index[last]++] = i;
}
//将数字依次取出
tmp = 0;
for (int i = 0; i < bucket.length; i++) {
for (int j = 0; j < index[i]; j++) {
arr[tmp++] = bucket[i][j];
}
}
//[66, 81, 99, 143, 473, 512]
}
}
|