1. 程式人生 > >排序演算法---最穩定的計數排序

排序演算法---最穩定的計數排序

演算法思想

有沒有一種排序演算法的時間複雜度為O(N)呢?
如果面試官這麼問你,千萬不要直接否定!
事實上是有線性時間複雜度的排序演算法,只不過其使用條件有限,只能是滿足條件的整數(0~n)序列,而且需要一定的輔助空間。這就是我們即將要提到的——計數排序。

對於排序演算法來說計數排序是穩定的,跟桶排序相比其所佔用的空間是可控的,跟其他比較排序相比它的速度又是快捷的。

其基本思想:用待排序的數作為計數陣列的下標,統計每個數字的個數。然後依次輸出即可得到有序序列。對每一個元素x,確定出小於x的元素個數。例如,如果有17個元素小於x,則x就是屬於第18個輸出位置。

這個演算法的步驟大致如下:
1. 初始化一個計數陣列,大小是輸入陣列中的最大的數。
2. 遍歷輸入陣列,遇到一個數就在計數陣列對應的位置上加一。例如:遇到5,就將計數陣列第五個位置的數加一。
3. 把計數陣列直接覆蓋到輸出陣列(節約空間)。

Java程式碼實現

public class CountSort {
    public static void main(String[] args) {
        System.out.println("輸入排序的個數n:");
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        int array[] = new int[n];
        System.out.println("請輸入要排序的數字:");
        for (int
i = 0; i < n; i++) { array[i] = input.nextInt(); } System.out.println("計數排序結果為:"); count(array); for (int i = 0; i < n; i++) { System.out.print(array[i] + " "); } } private static void count(int[] array) { if (array.length <= 1
) { return; } int max = 0; //尋找最大值 for (Integer i : array) { if (i > max) { max = i; } } int count[] = new int[max + 1];//建立輔助計數陣列 Arrays.fill(count, 0);//初始化陣列 //用待排序的數作為計數陣列的下標,統計每個數字的個數 for (int i = 0; i < array.length; i++) { count[array[i]]++; } //根據計數陣列,修改原陣列的順序 int k = 0; for (int i = 0; i <= max; i++) { for (int j = 0; j < count[i]; j++) { array[k++] = i; } } } }

這裡寫圖片描述

複雜度

跟桶排序一樣,計數排序的複雜度是線性的:
時間:O(n + k),n是輸入陣列長度,k是最大的數的大小。
空間:O(n + k),n是輸入陣列長度,k是最大的數的大小。