[toc]java
聲明:參考來源互聯網,有任何爭議能夠留言。站在前人的肩上,咱們才能看的更遠。本教程純手打,致力於最實用教程,不須要什麼獎勵,只但願多多轉發支持。
歡迎來我公衆號,但願能夠結識你,也能夠催更,微信搜索:JavaPub算法有任何問題均可以來談談 !數組
計數排序是比較容易的排序算法,可是對數量級較小的整數排序很實用。
計數排序是一個 非基於比較的排序算法,該算法於1954年由 Harold H. Seward 提出。它的優點在於在對 必定範圍內的 整數排序時,它的複雜度爲Ο(n+k)
(其中k是整數的範圍), 快於任何比較排序算法。固然這是一種犧牲空間換取時間的作法,並且當O(k)>O(n*log(n))
的時候其效率反而不如基於比較的排序(基於比較的排序的時間複雜度在理論上的下限是O(n*log(n)), 如 歸併排序, 堆排序)
例如:計數排序是用來排序0到100之間的數字的最好的算法,可是它不適合按字母順序排序人名。可是,計數排序能夠用在基數排序中的算法來排序數據範圍很大的數組。微信
若是有疑問,看下邊一個例子
題目:數組裏有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, 9
code
加1
操做。好比第一個整數是 9,那麼數組下標爲 9 的元素加 1:blog
最終,數列遍歷完畢時,數組的狀態以下:排序
數組中的每個值,表明了數列中對應整數的出現次數。教程
有了這個統計結果,排序就很簡單了,直接遍歷數組,輸出數組元素的下標值,元素的值是幾,就輸出幾回:
0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 9, 9, 9, 10
這就是計數排序的基本過程,它適用於必定範圍的整數排序。在取值範圍不是很大的狀況下,它的性能在某些狀況甚至快過那些O(nlogn)的排序,例如快速排序、歸併排序。
@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]
1. 當數列最大最小值差距過大時,並不適用於計數排序
好比給定20個隨機整數,範圍在0到1億之間,此時若是使用計數排序的話,就須要建立長度爲1億的數組,不但嚴重浪費了空間,並且時間複雜度也隨之升高。
2. 當數列元素不是整數時,並不適用於計數排序
若是數列中的元素都是小數,好比3.1415,或是0.00000001這樣子,則沒法建立對應的統計數組,這樣顯然沒法進行計數排序。