想要看更加舒服的排版、更加準時的推送
關注公衆號“不太靈光的程序員”
每日八點有乾貨推送
轉載自公衆號“不太靈光的程序員” 《基於桶子法實現的兩種排序算法》
閱讀原文
在前面的幾天我們學習了基於比較的排序算法,今天來了解下基於桶排序的兩個排序算法,桶排序不是一種具體的實現是一種排序思想。
桶排序是將數組中分到有限的桶裏,通俗的講就是我們已經有一些有限個數的、排好序的桶子,將相應屬性的數據放入對應的桶中,再按桶的順序取出,新的數組就是有序的了。
桶排序的侷限性??
當我們選擇的數據範圍比較小時,例如人的身高、考試分數、績效評級,數據基本上處在一個小的數值範圍內,但當我們對員工薪資進行排序時,數據範圍很大從幾千到幾萬的都有,需要的桶的數量非常多,且當這些數據分佈不均勻時,會造成很大的空間浪費。
計數排序
基於桶排序思想,但是每個桶只存儲單一鍵值。比如過我們要把公司員工安裝身高進行排序,分析一個成年人的身高是在1m3m之間,對應的釐米數是100cm300cm,我們需要創建100~300號的桶,然後我們把所有員工,按照他們的身高放入對應的桶中;然後從100號桶開始往外倒數據,員工被導出的順序就是員工升高的排序了。
- 時間複雜度O(N)
- 空間複雜度O(M) M是選擇的桶的數量
- 穩定排序
Python實現計數排序
def CountSort(nums):
# 以身高的最大最小值來確定桶的範圍
min_num = min(nums)
max_num = max(nums)
# 申請學生升高範圍的所有桶
count = {i: 0 for i in range(min_num, max_num+1)}
for i in nums:
count[i] += 1
return [key for key, value in count.items() for j in range(value)]
if __name__ == "__main__":
# 對一組學生身高進行排序
print(CountSort([175, 187, 183, 182, 163, 190, 159, 167]))
基數排序
基於桶排序思想,根據鍵值的每位數字來分配桶;首先我們假設數據組的所有元素都是十進制的,然後就準備0~9號桶;把每個數據的個位是幾就把它放入幾號桶,再從0號桶依次倒出數據,把每個數據的十位是幾就把它放入幾號桶,再從0號桶依次倒出數據;直到所有數的每位都重複到以上過程,0號桶依次倒出數據就是有序的了。
- 時間複雜度O(N)
- 空間複雜度O(M) M是選擇的桶的數量
- 穩定排序
Python實現基數排序
def RadixSort(nums):
# 首先要申請0-9的十個桶
def pour_out(arr):
return [i for value in arr.values() for i in value]
# 當前排序的位數 0個位,1十位,2百位等...
intm = 0
while 1:
count = {i: [] for i in range(10)}
for i in nums:
# 當前排序位 的數值
initn = i // 10 ** intm % 10
count[initn].append(i)
nums = pour_out(count)
intm += 1
if len(count[0]) == len(nums):
break
return count[0]
if __name__ == "__main__":
# 對一組學生身高進行排序
print(RadixSort([175, 187, 183, 182, 163, 190, 159, 167]))