計數排序(python)

2021-09-23 18:52:20 字數 2649 閱讀 7380

計數排序是乙個非基於比較的排序演算法。它的優勢在於在對一定範圍內的整數排序時,它的複雜度為ο(n+k)(其中k是整數的範圍),當o(k)< o(nlogn)時快於任何比較排序演算法。這是一種犧牲空間換取時間的做法,而且當o(k)>o(nlog(n))的時候其效率反而不如基於比較的排序(基於比較的排序的時間複雜度在理論上的下限是o(nlog(n)), 如歸併排序,堆排序)。作為一種線性時間複雜度的排序,計數排序要求輸入的資料必須是有確定範圍的整數。

計數排序的基本思想是對於給定的輸入序列中的每乙個元素x,確定該序列中值小於x的元素的個數(此處並非比較各元素的大小,而是通過對元素值的計數和計數值的累加來確定)。一旦有了這個資訊,就可以將x直接存放到最終的輸出序列的正確位置上。

計數排序只需遍歷一次資料,在計數陣列中記錄,輸出計數陣列中有記錄的下標,時間複雜度為o(n+k)。

這種演算法同時也有額外空間開銷計數陣列和結果陣列,空間複雜度為o(n+k)

找出待排序的陣列中最大和最小的元素;

統計陣列中每個值為i的元素出現的次數,存入陣列c的第i項;(由於這個原因,要排序的數必須在大於等於0,且由於時間複雜度的問題,陣列元素的上限也有一定的限制,否則,時間複雜度不如比較類排序。)對所有的計數累加(從c中的第乙個元素開始,每一項和前一項相加);

反向填充目標陣列:將每個元素i放在新陣列的第c(i)項,每放乙個元素就將c(i)減去1.

8.2.1 演算法舉例

以下說明下計數排序的過程。以《演算法導論》這本書的乙個例子進行說明:

初始化陣列: a[2,5,3,0,2,3,0,3]

假設我們已經事先知道a陣列的最大值5,排序過程如下:

a)建立乙個長度為6的臨時儲存陣列空間c,並將c陣列每乙個元素初始化為0。

b)統計重複元素的個數。a陣列的元素作為陣列c的下標,掃瞄陣列a,a陣列元素每出現一次,陣列c等於該元素的下標位置的元素加一。例如第一次掃瞄到的是2,則c[2]=0+1=1,…,第五次再次掃瞄到了2,c[2]=1+1=2,說明這個陣列2的個數為2個。c[2,0,2,3,0,1]

c)計算有多少(y)個元素小於或等於陣列c的下標。根據計數陣列累加得到c[2,2,4,7,7,8] (小於等於0的有2個,小於等於1的有2個,小於等於2的4個,…小於等於5的有8個)

d)倒序掃瞄陣列a的元素x,依次將元素放置於輸出序列res[y]位置,y為小於或者等於這個元素的個數,同時臨時陣列c[x]=c[x]-1;重複這個過程直至掃瞄到陣列a的首位元素。res[0,0,2,2,3,3,3,5]因為倒敘遍歷原陣列,不會改變原來相等元素的相對位置,所以這是穩定的

簡而言之就是先統計出陣列a元素x小於或等於自身的元素個數y,將x放置於res[y]處,y-1,接著重複這個過程。

簡而言之

以[5,3,6,6]陣列為例,小於等於5的元素個數為2,小於等於3的元素個數為1,小於等於6的元素個數為4。res = [0,0,0,0],從後往前遍歷原陣列,6,小於等於6的元素個數為4,最後乙個6,放在res[4-1]的位置,這是在剩下的元素中,小於等於6的個數為4-1=3;在繼續遍歷,6,小於等於6的元素個數為3,放在res[3-1]的位置。再繼續遍歷,3,這時候小於等於3的元素個數為1,不變,放在res[1-1]的位置;5,小於等於5的元素個數為2,放在res[2-1]的位置。

def

countingsort

(numlist)

: n =

len(numlist)

if n ==

0or n ==1:

return numlist

maxval =

max(numlist)

countarr =[0

for i in

range

(maxval+1)

]for i in numlist:

countarr[i]+=1

for i in

range(1

,len

(countarr)):

countarr[i]

+= countarr[i-1]

res =[0

for i in

range

(n)]

for i in

range

(n-1,-

1,-1

):res[countarr[numlist[i]]-

1]= numlist[i]

countarr[numlist[i]]-=

1# 必須要減1,由於待排序元素在res中的位置是由計數陣列的值來決定的。

# 當遍歷了元素x之後,小於x的元素不會受影響,大於x的元素不會受影響,

# 只有等於x的元素會受影響,在往res中壓的時候,要比x的位置往前移動一位,

# 因此需要將計數陣列中的下標為x的值減1,使得下次在遍歷到x的時候,

# 壓入的位置在前乙個x的位置之前

return res

numlist=[5

,8,9

,3,2

,5,1

,6,8

]print

(countingsort(numlist)

)# 輸出結果為:[1, 2, 3, 5, 5, 6, 8, 8, 9]

python計數排序 Python 計數排序

1.python coding utf 8 def counting sort a,b,k 計數排序,偽碼如下 counting sort a,b,k 1 for i 0 to k 初始化儲存區的值 2 do c i 0 3 for j 1 to length a 為各值計數 4 do c a j ...

python計數排序

對每個元素確定小於該元素的個數 def countsort a,k k是元素數值上界 c 0 k result 0 len a for i in range len a c a i c a i 1 計算小於該元素的個數 for i in range k 1 c i 1 c i 1 c i 每個減輕去...

計數排序 python

以下以 1,3,5,8,2,5,4 這組數字來演示。首先,我們找到這組數字中最大的數,也就是 bucketlen 8,建立乙個最大下標為 8 的空陣列 bucket 遍歷資料,將資料的出現次數填入bucket中對應的下標位置中。遍歷 bucket 將資料依次取出即可。def countingsort...