計數排序(Counting Sort)Java

常見的排序算法,例如:冒泡,選擇,快速等等。他們都是基於比較實現的排序算法。最快的快速排序算法的時間複雜度爲O(nlogn)O(nlogn)。而計數排序是一種特殊的排序算法,它的時間複雜度爲O(3n+k)O(3n+k),在數據較多數據範圍較小的情況下,計數排序比快速排序的效率更高。與此同時,計數排序是穩定的,相同的數據相對順序保持不變。

示例:待排序數組array爲[98, 97, 96, 98, 95, 100, 96, 98, 100, 99]。
算法步驟:
1、找到最小值min,最大值max,得到數據的極差1range = max - min + 1。
2、創建計數數組count,大小爲range。
3、順序遍歷原數組,索引爲i,數據element = array[i],映射到count數組中索引爲index = element - min,將count[index]加1。表示數組中的元素element的個數加1。
4、順序遍歷count數組,索引爲i,計算count[i] = count[i - 1] + count[i]。
5、逆序遍歷原數組array,索引爲i,數據element = array[i],映射到count數組中索引爲index = element - min,將count[index]減1後的數據爲j,然後將element保存到結果數組(res)中的索引爲j的位置。

演示視頻如下:

計數排序

由此可以看出:算法共有四次循環,其中三次遍歷原數組,時間複雜度爲O(n)O(n),若數據範圍爲k,則遍歷count數組的時間複雜度爲O(k)O(k),故總的時間複雜度爲O(3n+k)O(3n+k)。不計算輸出數組的情況下,空間複雜度爲O(k)O(k)
可以發現,數據範圍對計數排序的複雜度影響較大。因此當數據範圍非常大的時候不宜使用此算法。

Java代碼實現如下:

/**
 * 計數排序
 * <p>創建日期:2020-06-05 11:56</p>
 *
 * @author PengHao
 */
public class CountSort {
    /**
     * <p>計數排序</p>
     * <p>時間複雜度爲O(3n+k)</p>
     * <p>空間複雜度爲O(k)</p>
     *
     * @param src 待排序數組
     * @return 排好序的數組
     */
    public static int[] countSort(int[] src) {
        // 數組中的最小值
        int min = src[0];
        // 數組中的最大值
        int max = src[0];
        for (int value : src) {
            if (value < min) {
                min = value;
            } else if (value > max) {
                max = value;
            }
        }

        // 數組中的數據範圍
        int range = max - min + 1;
        // count[i]表示數組src中數據min + i的個數
        int[] count = new int[range];
        for (int value : src) {
            count[value - min]++;
        }

        // 累計,使得count[i]保存src中小於等於min + i的數據的個數
        for (int i = 1; i < range; i++) {
            count[i] += count[i - 1];
        }

        // 結果數組
        int[] res = new int[src.length];
        // 倒序遍歷原數組,保持排序的穩定性
        for (int i = src.length - 1; i >= 0; i--) {
            // 獲取數據在count數組中的索引
            int index = src[i] - min;
            // 個數減1
            count[index]--;
            // 數據src[i]排序後的索引是count[index]
            res[count[index]] = src[i];
        }
        return res;
    }
}

代碼沒有進行安全檢查,所以待排序數組不能爲空,並且至少有1個元素。


  1. 數學中極差的定義爲:range = max - min。 ↩︎

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