不完全基於比較的桶排序(Java語言描述)

所謂“桶排序”,是一種線性時間的排序算法,需要建立多個“桶”協助排序。
每一個“桶”代表一個區間範圍,裏面可以盛裝一個或多個元素(也可以不裝元素)。

具體如何建立多少個桶,如何確定桶的範圍,有很多不同的方式。
這裏創建的桶的數量等於原始序列的元素數量,除最後一個桶只包含數組的最大元素外,前面各個桶的區間按照比例決定:
區間跨度 = (最大值-最小值)/(桶的數量-1)

public static double[] bucketSort(double[] array) {
    //得到數組的最大值和最小值並計算出差值
    double max = array[0];
    double min = array[0];
    for (int i = 1; i < array.length; i++) {
        if (array[i] > max) {
            max = array[i];
        }
        if (array[i] < min) {
            min = array[i];
        }
    }
    double d = max - min;
    //初始化桶
    int bucketNum = array.length;
    ArrayList<LinkedList<Double>> bucketList = new ArrayList<>(bucketNum);
    for (int i = 0; i < bucketNum; i++) {
        bucketList.add(new LinkedList<Double>());
    }
    //遍歷原始數組,將每個元素放入桶中
    for (int i = 0; i < array.length; i++) {
        int num = (int)((array[i]-min) * (bucketNum-1) / d);
        bucketList.get(num).add(array[i]);
    }
    //對每個桶內部的元素進行排序
    for (int i = 0; i < bucketList.size(); i++) {
        //JDK底層採用了歸併排序或者歸併排序的優化版本
        Collections.sort(bucketList.get(i));
    }
    //輸出全部元素
    double[] sortedArray = new double[array.length];
    int index = 0;
    for (LinkedList<Double> list : bucketList) {
        for (double element : list) {
            sortedArray[index] = element;
            index++;
        }
    }
    return sortedArray;
}

桶排序的時間複雜度和空間複雜度均爲O(N)。

桶排序的性能不能說是完全穩定的。如果元素分佈極爲不均衡,在極端情況下,第一個桶有n-1個元素,最後一個桶有1個元素。此時時間複雜度退化到O(NlogN),而且有很多空桶,浪費空間。

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