計數排序——python(穩定版排序)
阿新 • • 發佈:2019-01-08
from __future__ import print_function
def counting_sort(collection):
"""
計數排序
演算法思想:
假設要排序的陣列為 A = {1,0,3,1,0,1,1}這裡最大值為3,最小值為0,
那麼我們建立一個數組C,長度為3+1-0=4。然後一趟掃描陣列A,得到A中各個元素的總數,
並保持到陣列C的對應單元中。比如0 的出現次數為2次,則 C[0] = 2;1 的出現次
數為4次,則C[1] = 4。C=[2,4,0,1]由於C 是以A的元素為下標的,所以這樣一做,A中的元素在C
中自然就成為有序的了,然後我們分別統計比0,1,3小的元素個數,如比1小(包括1)的元素有6個。更新
C,C=[2,6,0,7],更新C是為了保證排序穩定。然後把這個在C中的記錄按每個元素的計數展開到輸出陣列B中,
排序就完成了。 也就是B[0] 到 B[1] 為0, B[2] 到 B[5] 為1 這樣依此類推。
Examples:
>>> counting_sort([0, 5, 3, 2, 2])
[0, 2, 2, 3, 5]
>>> counting_sort([])
[]
>>> counting_sort([-2, -5, -45])
[-45, -5, -2]
"""
# 輸入為空,就返回空列表
if collection == []:
return []
coll_len = len(collection)
coll_max = max(collection)#返回最大值
coll_min = min(collection)#返回最小值
#計算待排序列表的元素數值區域長度,如4-9共9+1-4=6個數
counting_arr_length = coll_max + 1 - coll_min
counting_arr = [0] * counting_arr_length #構造一個全為0列表
for number in collection:
counting_arr[number - coll_min] += 1 #統計列表中每個值出現的次數,
#使counting_arr[i]存放<=i的元素個數,就是待排序列表中比某個值小的元素有多少個
for i in range(1, counting_arr_length):
counting_arr[i] = counting_arr[i] + counting_arr[i-1]
ordered = [0] * coll_len #存放排序結果
#使每個元素被放在ordered中正確的位置,升序
for i in reversed(range(0, coll_len)): #reversed表示從下標最大的位置到0,為了使排序穩定
ordered[counting_arr[collection[i] - coll_min]-1] = collection[i]#-1是因為下標從0開始的
counting_arr[collection[i] - coll_min] -= 1 #每歸位一個元素,就少一個元素
return ordered
if __name__ == '__main__':
try:
raw_input # Python 2
except NameError:
raw_input = input # Python 3
user_input = raw_input('輸入待排序的數,用\",\"分隔:\n').strip()
#strip() 方法用於移除字串頭尾指定的字元(預設為空格)
unsorted = [int(item) for item in user_input.split(',')]
print(counting_sort(unsorted))
一些說明:
- 我的github專案上有完整的演算法程式碼,歡迎star,fork.
- 這裡的所有演算法均用python實現,“翻譯”自國外某程式設計師的專案。