計數排序就是這麼容易

在這裏插入圖片描述

前言

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

本教程純手打,致力於最實用教程,不需要什麼獎勵,只希望多多轉發支持。
歡迎來我公衆號,希望可以結識你,也可以催更,微信搜索: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,如下所示:

先假設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這樣子,則無法創建對應的統計數組,這樣顯然無法進行計數排序。

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