前言
聲明:參考來源互聯網,有任何爭議可以留言。站在前人的肩上,我們才能看的更遠。
本教程純手打,致力於最實用教程,不需要什麼獎勵,只希望多多轉發支持。
歡迎來我公衆號,希望可以結識你,也可以催更,微信搜索: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.步驟
- 算法的步驟如下:
- 找出待排序的數組中最大和最小的元素
- 統計數組中每個值爲i的元素出現的次數,存入數組C的第i項
- 對所有的計數累加(從C中的第一個元素開始,每一項和前一項相加)
- 反向填充目標數組:將每個元素i放在新數組的第C(i)項,每放一個元素就將C(i)減去1
如果有疑問,看下邊一個例子
2.2.實例題目
題目:數組裏有20個隨機數,取值範圍爲從0到10,要求用最快的速度把這20個整數從小到大進行排序。
無論是歸併排序,冒泡排序還是快速排序等等,都是基於元素之間的比較來進行排序的。但是有一種特殊的排序算法叫計數排序,這種排序算法不是基於元素比較,而是利用 數組下標
來確定元素的正確位置。
通過計數排序特性分析題目,我們知道整數的取值範圍是從0到10,那麼這些整數的值肯定是在0到10這11個數裏面。於是我們可以建立一個長度爲11的數組,數組下標從0到10,元素初始值全爲0,如下所示:
先假設20個隨機整數的值是: 9, 3, 5, 4, 9, 1, 2, 7, 8,1,3, 6, 5, 3, 4, 0, 10, 9, 7, 9
- 讓我們先遍歷這個無序的隨機數組,每一個整數按照其值對號入座,對應數組下標的元素進行
加1
操作。
比如第一個整數是 9,那麼數組下標爲 9 的元素加 1:
- 第二個整數是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這樣子,則無法創建對應的統計數組,這樣顯然無法進行計數排序。