排序算法之基數排序【Java版】

引言

本篇是排序算法的最後一篇,基數排序,桶排序的升級版。

1、算法步驟

1、首先對一組數據按照個位上的數字進行桶排序
2、然後對這組數據繼續按照十位上的數字進行桶排序
3、依次循環至這組數據的最大數位置上,排序就完成了。

2、時間複雜度

平均時間複雜度O(n + k)

3、算法實現

public class RadixSort {

    public static void main(String[] args) {
        int[] numbers = {12,2,24,30,6,16};
        int[] result = RadixSort.sort(numbers);
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < result.length; i++) {
            stringBuffer.append(result[i] + " ");
        }
        System.out.println(stringBuffer.toString());
    }
    
    public static int[] sort(int[] numbers){
        int[] needSort = Arrays.copyOf(numbers, numbers.length);
        //獲取最大數的位數
        int maxLength = getMaxLength(needSort);
        //根據位數依次排序
        return radixSort(needSort, maxLength);
    }

    public static int getMaxLength(int[] arg){
        //獲取最大的數
        int maxValue = arg[0];
        for (int i = 1; i < arg.length; i++) {
            if(maxValue < arg[i]){
                maxValue = arg[i];
            }
        }
        //獲取最大數位數
        if(maxValue == 0){
            return 1;
        }
        int maxLength = 0;
        for (long temp = maxValue; temp != 0; temp /= 10) {
            maxLength++;
        }
        return maxLength;
    }

    public static int[] radixSort(int[] arg,int maxLength){
        //位數
        int dev = 1;
        //10進制
        int hex = 10;
        for (int i = 0; i < maxLength; i++,dev *= 10,hex *= 10) {
            // 考慮負數的情況,這裏擴展一倍隊列數,其中 [0-9]對應負數,[10-19]對應正數 (bucket + 10)
            int[][] counter = new int[hex * 2][0];
            for (int j = 0; j < arg.length; j++) {
                int bucket = (arg[j] % hex) / dev + hex;
                counter[bucket] = arrayAppend(counter[bucket],arg[j]);
            }

            int length = 0;
            for (int[] bucket : counter) {
                for (int value : bucket){
                    arg[length++] = value;
                }
            }
        }
        return arg;
    }

    private static int[] arrayAppend(int[] arr, int value) {
        arr = Arrays.copyOf(arr, arr.length + 1);
        arr[arr.length - 1] = value;
        return arr;
    }
}

4、總結

計數排序中每個桶只存儲單一數值,有很多空桶浪費了;桶排序中,每個桶存儲一定範圍的數值,每個桶中的數據仍需再排序;基數排序是根據鍵值的每位數字來分配桶。

結束語

排序算法到此結束,現在入職新公司,在熟悉業務和代碼中,後面有時間刷LeetCode的時候會再進行總結。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章