算法 - 排序 - 計數排序

1. 原理

計數排序不是基於比較的排序算法,其核心在於將輸入的數據值轉化爲鍵存儲在額外開闢的數組空間中。 作爲一種線性時間複雜度的排序,計數排序要求輸入的數據必須是有確定範圍的整數。

計數排序(Counting sort)是一種穩定的排序算法。計數排序使用一個額外的數組C,其中第i個元素是待排序數組A中值等於i的元素的個數。然後根據數組C來將A中的元素排到正確的位置。它只能對整數進行排序。

2. 算法描述

  1. 找出待排序的數組中最大和最小的元素;
  2. 統計數組中每個值爲i的元素出現的次數,存入數組C的第i項;
  3. 對所有的計數累加(從C中的第一個元素開始,每一項和前一項相加);
  4. 反向填充目標數組:將每個元素i放在新數組的第C(i)項,每放一個元素就將C(i)減去1。

3. 算法分析

當輸入的元素是n個0到k之間的整數時,它的運行時間是 O(n + k)。計數排序不是比較排序,排序的速度快於任何比較排序算法。由於用來計數的數組C的長度取決於待排序數組中數據的範圍(等於待排序數組的最大值與最小值的差加上1),這使得計數排序對於數據範圍很大的數組,需要大量時間和內存。

排序方式:out-place

時間複雜度:

最佳情況:T(n) = O(n+k)
最差情況:T(n) = O(n+k)
平均情況:T(n) = O(n+k)
空間複雜度:O(k)

4.  動圖演示

在這裏插入圖片描述

5. 代碼

 public static void main(String[] args) {
        int[] arrs = RandomArr.createIntArr(30, 0, 100);
        int[] arrs2 = Arrays.copyOf(arrs, arrs.length);
        Arrays.stream(arrs).forEach(l -> {
            System.out.print(l + " ");
        });
        System.out.println();
        CountSort(arrs);

        Arrays.stream(arrs).forEach(l -> {
            System.out.print(l + " ");
        });
        System.out.println();
        Arrays.stream(arrs2).sorted().forEach(l -> {
            System.out.print(l + " ");
        });
    }

    public static void CountSort(int[] arrs) {


        // 1、先找到其最大值
        int index = 0;
        for (int i = 1; i < arrs.length; i++) {
            if (arrs[i] > arrs[index]) {
                index = i;
            }
        }

        // 2、創建最大值長度的數組
        int[] arrC = new int[arrs[index] + 1];
        // 3、對待排序數組進行反相統計
        for (int i = 0; i < arrs.length; i++) {
            arrC[arrs[i]]++;
        }

        // 4、排序輸出
        index = 0;
        for (int i = 0; i < arrs.length; i++) {
            for (; ; ) {
                if (arrC[index]-- > 0) {
                    arrs[i] = index;
                    break;
                }
                index++;
            }
        }
    }

 

 

 

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