Java 基数排序

版权声明:本文为博主原创文章,未经博主允许不得转载。 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

猜你喜欢

转载自blog.csdn.net/afei__/article/details/82971310