什麼是計數排序?

2022-09-02 09:36:10 字數 3831 閱讀 8758

假設,有20個隨機整數,取值範圍是0到10,需要對其排序。可能第一反應是使用快速排序啊,快排的時間複雜度是o(nlog n)!但是,可不可以比o(nlog n)更快呢?這就是這篇文章要介紹的計數排序(從名字上來看,就是計算數字出現頻次的排序方法,非常的見名知意)。

因為取值範圍是0到10(整數的值在0,1,2,3,4,5,6,7,8,9,10裡),共有11個數值,所以需要11個坑,我們定義乙個長度是12的陣列array,每個元素的初始值是0,然後對20個隨機整數進行迴圈,對應的元素值加1。最後,輸出array,就是排好序的。

比如有20個整數,分別是 9,2,8,5,1,8,6,9,5,8,1,5,8,3,4,7,0,6,2,10

初始化陣列array

陣列下標01

2345

6789

10頻率00

0000

0000

0要排序的隨機整數,第乙個值是9,那陣列下標是9的分布值加1,所以array變成

陣列下標01

2345

6789

10頻率00

0000

0001

0第二個值是2,陣列下標是2的分布值加1

陣列下標01

2345

6789

10頻率00

1000

0001

0後面的以此類推。最終輸出array,元素的值是幾,就輸出幾次。這個陣列顯然是有序的了。   

陣列下標01

2345

6789

10頻率12

2113

2142

1**如下

def sort(array):

# 1.獲取陣列內的最大值和最小值,來確定陣列的size

max = array[0]

min = array[0]

for i in array:

if i > max:

max = i

if i < min:

min = i

# 2.定義定長陣列,陣列的元素初始值是0(這裡偷懶使用了列表生成式)

sort_array = [0 for i in range(max - min + 1)]

# 3.計數

for i in array:

sort_array[i - min] = sort_array[i - min] + 1

# 4.獲得排序後的陣列

sortarray = [0 for i in array]

index = 0

for i, value in enumerate(countarray):

for j in range(1, value + 1):

sortarray[index] = i + min

index = index + 1

return sortarray

if __name__ == "__main__":

array = [9, 2, 8, 5, 1, 8, 6, 9, 5, 8, 1, 5, 8, 3, 4, 7, 0, 6, 2, 10]

sort_array = sort(array)

print(sort_array)

下面是輸出結果

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

process finished with exit code 0

從**實現來看,也不複雜,甚至很簡單。

上面的演算法,因為有乙個雙重fou迴圈,還可以在優化下。

假設考試是十分制的,共有20個同學,同學的考試成績是上面的那20個數(9, 2, 8, 5, 1, 8, 6, 9, 5, 8, 1, 5, 8, 3, 4, 7, 0, 6, 2, 10),考試獲得9分的有兩個同學,那到底誰是第

二、誰是第三呢?

上面的**,需要公升級一下,頻率一欄,需要變成「分布值」了,它的值是上一格的值和自身的值之和

陣列下標01

2345

6789

10分布值

13(1+2)

5(3+2)

6(5+1)

7(6+1)

10(7+3)

12(10+2)

13(12+1)

17(13+4)

19(17+2)

20(19+1)

然後對分布值陣列輸出,第乙個是下標10的,遍歷之後分布值**的下標10的分布值就減1,它是第一名(總人數-分布值+1)

陣列下標01

2345

6789

10分布值13

56710

1213

1719

19(20-1)

假如獲得9分的是張三和李四,遍歷張三之後,**下標9的值減1,它是第二名(2 = 20-19 +1)

陣列下標01

2345

6789

10分布值13

56710

1213

1718(19-1)

19李四是第三名(3 = 20 -18 + 1)

陣列下標01

2345

6789

10分布值13

56710

1213

1717(18-1)

19這樣的話,相同分數的同學,就分出分數排名了。

def sort2(array):

# 1.獲取陣列內的最大值和最小值,來確定陣列的size

max = array[0]

min = array[0]

for i in array:

if i > max:

max = i

if i < min:

min = i

# 2.定義定長陣列,陣列的元素初始值是0(這裡偷懶使用了列表生成式)

countarray = [0 for i in range(max - min + 1)]

# 3.計數

for i in array:

countarray[i - min] = countarray[i - min] + 1

# 4.計數的陣列變形

sum = 0

for i,value in enumerate(countarray):

sum = sum + value

countarray[i] = sum

# 5.獲得排序後的陣列

sortarray = [0 for i in array]

for i in array:

sortarray[countarray[i - min] - 1] = i

countarray[i - min] = countarray[i - min] - 1

return sortarray

if __name__ == "__main__":

array = [9, 2, 8, 5, 1, 8, 6, 9, 5, 8, 1, 5, 8, 3, 4, 7, 0, 6, 2, 10]

sort_array = sort2(array)

print(sort_array)

假設array元素有n個,取值範圍是m。

時間複雜度:3n(步驟1、步驟3、步驟5) + m(步驟4),去掉係數,時間複雜度是o(n+m)

空間複雜度:只考慮統計陣列,那就是m

陣列的元素有小數。比如有乙個元素是1.001,這種建立統計陣列的話,那代價就太大太大了。

陣列內的元素跨度大。假如有十個數,最大是1000,最小是1,使用計排的話,得建立1000個長度的陣列,這顯然也不合適的。

什麼是計數排序?

public static int countsort int array 2.根據數列最大值確定統計陣列的長度 int countarray newint max 1 3.遍歷數列,填充統計陣列 for inti 0 i countarray array i 4.遍歷統計陣列,輸出結果 intin...

什麼是計數排序?

有這樣一道排序題 陣列裡有20個隨機數,取值範圍為從0到10,要求用最快的速度把這20個整數從小到大進行排序。第一時間你可能會想使用快速排序,因為快排的時間複雜度只有o nlogn 但是這種方法還是不夠快,有沒有比o nlogn 更快的排序方法呢?你可能會有疑問 o nlogn 已經是最快的排序演算...

什麼是計數排序?

計數排序其實是桶排序的一種特殊情況。當要排序的 n 個資料,所處的範圍並不大的時候,比如最大值是 k,我們就可以把資料劃分成 k 個桶。每個桶內的資料值都是相同的,省掉了桶內排序的時間。我們都經歷過高考,高考查分數系統你還記得嗎?我們查分數的時候,系統會顯示我們的成績以及所在省的排名。如果你所在的省...