版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/afei__/article/details/82971310
一、简介
基数排序是这样一种排序算法,我们可以从低位(个位)开始,根据个位数排序一次,然后根据十位数排序,再根据百位数进行排序……最终完成整个数组的排序。
对于十进制数字而言,每一位只会是 0~9 这十个数字,我们通常使用桶排序(计数排序)来完成每一位数的排序。桶排序是一种稳定的排序算法,基数排序的正确性依赖一种稳定的排序算法。
基数排序其实是分 LSD(从低位向高位排序) 和 MSD(从高位向低位排序) 两种。
二、示意图
三、时间复杂度
基数排序的时间复杂度为 O(n)。
基数排序使用桶排序对其每一位进行排序,即每一位的排序时间复杂度为 O(n),假设最大的数有 digit 位,则共需要进行 digit * O(n) 次排序。时间复杂度依旧为 O(n)。
四、代码示例
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
int[] arr = new int[] { 321, 1234, 543, 324, 24, 960, 540, 672, 783, 1000 };
radixSort(arr);
printArray(arr);
}
public static void radixSort(int[] arr) {
int digit = getMaxDigit(arr); // 获取最大的数是多少位
for (int i = 0; i < digit; i++) {
bucketSort(arr, i); // 执行 digit 次 bucketSort 排序即可
}
}
public static int getMaxDigit(int[] arr) {
int digit = 1; // 默认只有一位
int base = 10; // 十进制每多一位,代表其值大了10倍
for (int i : arr) {
while (i > base) {
digit++;
base *= 10;
}
}
return digit;
}
public static void bucketSort(int[] arr, int digit) {
int base = (int) Math.pow(10, digit);
// init buckets
ArrayList<ArrayList<Integer>> buckets = new ArrayList<ArrayList<Integer>>();
for (int i = 0; i < 10; i++) { // 只有0~9这十个数,所以准备十个桶
buckets.add(new ArrayList<Integer>());
}
// sort
for (int i : arr) {
int index = i / base % 10;
buckets.get(index).add(i);
}
// output: copy back to arr
int index = 0;
for (ArrayList<Integer> bucket : buckets) {
for (int i : bucket) {
arr[index++] = i;
}
}
}
public static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
执行结果:
24 321 324 540 543 672 783 960 1000 1234
五、使用基数排序实现英文单词字母表顺序排序
基数排序也不局限于对自然数进行排序,它也是一种适合对英文单词排序的一种线性时间(时间复杂度 O(n))的排序算法。
具体实现跳转至:https://blog.csdn.net/afei__/article/details/82971490