資料結構 計數排序學習筆記

2021-10-09 21:58:37 字數 2641 閱讀 9490

數值範圍小,且都是整型的數列進行排序,並且有嚴格的時間複雜度要求(小於o(n * logn)),常使用計數排序。

比如我有10億個數,但這些數都是位於0到10的整型資料,要求時間複雜度嚴格小於o(n * logn)。

首先我們檢視適合計數排序的資料特點:

①資料量沒有限制,但數值都集中在很小的範圍內,比如0~100;

②資料型別必須要是整型的,結合特點①即資料取值只有很少的整形範圍。

假定有20個待排序數列:

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

可以看到它們都是處於 [0,10] 內的整形資料

計數排序首先就是建立乙個計數陣列(視待排序資料量大小選擇使用 int 、long 、short等資料型別進行陣列初始化),計數陣列的長度和待排序資料不同的數值個數有關。

比如上面20個待排序陣列,取值範圍是0到10,初始化時我們可以選擇 byte 或者 short 作為陣列資料型別來建立乙個長度為 11 的計數陣列。

如果待排序陣列的取值不連續,比如 1,11,21這種,那麼我們可以建立長度為3的陣列,根據 num/10 的結果判斷資料應該填入哪乙個下標中。

然後遍歷待排序數列,對每次訪問的資料進行判斷,對應計數陣列下標的元素進行加一操作。

第乙個資料是 9 ,則對計數陣列下標為 9 的元素進行 +1 操作;

第二個資料是 3 ,則對計數陣列下標為 3 的元素進行 +1 操作。

最終遍歷完成後,計數陣列會統計下標對應的整型資料共出現了多少次,我們根據陣列下標和出現次數即可還原出有序的數列。

計數陣列下標01

2345

6789

10計數陣列元素12

1322

1214

1那麼輸出的有序序列就是:

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

樸素計數排序:根據最大值和最小值得出計數陣列長度,然後建立數值和下標的偏移關係,維護計數陣列來進行排序。

public

void

countsort

(int

nums)

//計算 計數陣列長度

int len = max - min +1;

int[

] countarray =

newint

[len]

;//遍歷原序列

for(

int num:nums)

//輸出排序後的序列

int index =0;

for(

int i=

0;i)for

(int j=

0;j;j++

)//根據偏移恢復資料

nums[index++]=

(i+min)

;}

當然計數排序還有一些短板,比如不穩定,計數陣列某個元素>1 時,其對應的資料先後順序就會亂掉。

為此可以將計數陣列變形,計數陣列從第二個元素開始,每乙個元素都加上前面所有元素之和,得到乙個統計排名的陣列:

排名陣列下標01

2345

6789

10排名陣列元素13

47911

1214

1519

20這個排名陣列中儲存的就是對應整數的最終排序位置。

獲得排名陣列後,我們從後往前遍歷原始數列,每次取出整數 i ,並訪問排名陣列,找到整數 i 對應下標,取出排名陣列元素 m ,將整數 i 插入最終序列中第 m 個位置,並把排名陣列中的m - 1,代表下一次遇到整數 i 時,將這乙個 i 插入到序列第 m - 1 的位置。

比如初始序列最後乙個資料是 9 ,代表小黃得了 9 分,

它對應排名陣列元素為 19 ,則把小黃的 9 插入到最終序列的第19位,

同時排名陣列中的 19 - 1 = 18,

下一次再遇到小明的 9 時,插到第18位,也就是小黃的前面,保證了排序的穩定。

改進計數排序:在樸素計數排序的基礎上,維護排名陣列保持排序的穩定性。

public

void

countsort2

(int

nums)

//計算 計數陣列長度

int len = max - min +1;

int[

] countarray =

newint

[len]

;//遍歷原序列

for(

int num:nums)

//維護排名陣列

int sum =0;

for(

int i=

0;i)//輸出最終排序,注意要從後往前遍歷

int[

] clonearray = nums.

clone()

;for

(int i=clonearray.length-

1;i>=

0;i--

)}

改進的計數排序,由於多了乙個維護排名陣列的操作,因此時間複雜度由 o(3n) 變為 o(3n + m),簡化為 o(n + m)。

資料結構 計數排序

題目來自灰灰考研 counting sort基本思想 對於給定的輸入序列中的每乙個元素x,確定該序列中值小於x的元素的個數 一旦有了這個資訊,就可以將x直接存放到最終的輸出序列的正確位置上。它建立乙個長度為這個資料範圍的陣列c,c中每個元素記錄要排序陣列中對應記錄的出現個數。下面以示例來說明這個演算...

資料結構 計數排序

計數排序基於桶排序。比如待排陣列 a 5 那麼就需要建造 105 max 100 min 1 6 大小的臨時陣列,將這 5 個元素按照,值減 100 min 作為下標儲存在臨時陣列中。如下圖所示 計數排序 param a paramn private static void jishu int a,...

資料結構 計數排序

之前講到的插入 希爾 選擇 堆 冒泡 快速 歸併排序都屬於比較排序 涉及到兩個數的比較 接下來要講到一種非比較排序演算法 計數排序。1 什麼是計數排序 計數排序是一種非比較性質的排序演算法,元素從未排序狀態變為已排序狀態的過程,是由額外空間的輔助和元素本身的值決定的。計數排序過程中不存在元素之間的比...