計數排序就是這麼容易

[toc]java

image.png

前言

聲明:參考來源互聯網,有任何爭議能夠留言。站在前人的肩上,咱們才能看的更遠。

本教程純手打,致力於最實用教程,不須要什麼獎勵,只但願多多轉發支持。
歡迎來我公衆號,但願能夠結識你,也能夠催更,微信搜索:JavaPub算法

有任何問題均可以來談談 !數組

計數排序是比較容易的排序算法,可是對數量級較小的整數排序很實用。

1.計數排序(Counting Sort)

1.1.計數排序(Counting Sort)

計數排序是一個 非基於比較的排序算法,該算法於1954年由 Harold H. Seward 提出。它的優點在於在對 必定範圍內的 整數排序時,它的複雜度爲 Ο(n+k)(其中k是整數的範圍), 快於任何比較排序算法。固然這是一種犧牲空間換取時間的作法,並且當 O(k)>O(n*log(n)) 的時候其效率反而不如基於比較的排序(基於比較的排序的時間複雜度在理論上的下限是O(n*log(n)), 如 歸併排序堆排序

例如:計數排序是用來排序0到100之間的數字的最好的算法,可是它不適合按字母順序排序人名。可是,計數排序能夠用在基數排序中的算法來排序數據範圍很大的數組。微信

  • 計數排序是一個簡單的排序算法,看下邊原理很容易理解。

2.原理

2.1.步驟

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

若是有疑問,看下邊一個例子

2.2.實例題目

題目:數組裏有20個隨機數,取值範圍爲從0到10,要求用最快的速度把這20個整數從小到大進行排序。

不管是[歸併排序](),[冒泡排序]()仍是[快速排序]()等等,都是基於元素之間的比較來進行排序的。可是有一種特殊的排序算法叫計數排序,這種排序算法不是基於元素比較,而是利用 數組下標 來肯定元素的正確位置。性能

經過計數排序特性分析題目,咱們知道整數的取值範圍是從0到10,那麼這些整數的值確定是在0到10這11個數裏面。因而咱們能夠創建一個長度爲11的數組,數組下標從0到10,元素初始值全爲0,以下所示:spa

先假設20個隨機整數的值是: 9, 3, 5, 4, 9, 1, 2, 7, 8,1,3, 6, 5, 3, 4, 0, 10, 9, 7, 9code

  • 讓咱們先遍歷這個無序的隨機數組,每個整數按照其值對號入座,對應數組下標的元素進行 加1 操做。

好比第一個整數是 9,那麼數組下標爲 9 的元素加 1:blog

  • 第二個整數是3,那麼數組下標爲 3 的元素加 1:

  • 繼續遍歷數列並修改數組......

最終,數列遍歷完畢時,數組的狀態以下:排序

數組中的每個值,表明了數列中對應整數的出現次數。教程

有了這個統計結果,排序就很簡單了,直接遍歷數組,輸出數組元素的下標值,元素的值是幾,就輸出幾回:

0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 9, 9, 9, 10

這就是計數排序的基本過程,它適用於必定範圍的整數排序。在取值範圍不是很大的狀況下,它的性能在某些狀況甚至快過那些O(nlogn)的排序,例如快速排序、歸併排序。

3.代碼

3.1.代碼

@Test
public void sortJavaPub(){
    int [] array = {2,1,5,3,4};
    //1.獲得數列的最大值
    int max = array[0];
    for (int i = 1; i < array.length; i++) {
        if (array[i] > max)
            max = array[i];
    }
    //2.根據數列的最大值肯定統計數組的長度
    int[] coutArray = new int[max + 1];
    //3.遍歷數列,填充統計數組
    for(int i = 0; i < array.length; i++)
        coutArray[array[i]]++;

    //4.遍歷統計數組,輸出結果
    int index = 0;
    int[] sortedArray = new int[array.length];
    for (int i = 0; i < coutArray.length; i++) {
        for (int j = 0; j < coutArray[i]; j++) {
            sortedArray[index++] = i;
        }
    }
    System.out.println(Arrays.toString(sortedArray));
}

返回結果:

[1, 2, 3, 4, 5]

4.擴展閱讀

4.1.侷限性

1. 當數列最大最小值差距過大時,並不適用於計數排序

好比給定20個隨機整數,範圍在0到1億之間,此時若是使用計數排序的話,就須要建立長度爲1億的數組,不但嚴重浪費了空間,並且時間複雜度也隨之升高。

2. 當數列元素不是整數時,並不適用於計數排序

若是數列中的元素都是小數,好比3.1415,或是0.00000001這樣子,則沒法建立對應的統計數組,這樣顯然沒法進行計數排序。

相關文章
相關標籤/搜索