【數據結構與算法Python實踐系列】基於桶子法實現的兩種排序算法(計數排序和基數排序)

想要看更加舒服的排版、更加準時的推送
關注公衆號“不太靈光的程序員”
每日八點有乾貨推送
轉載自公衆號“不太靈光的程序員” 《基於桶子法實現的兩種排序算法》
閱讀原文

在前面的幾天我們學習了基於比較的排序算法,今天來了解下基於桶排序的兩個排序算法,桶排序不是一種具體的實現是一種排序思想。

桶排序是將數組中分到有限的桶裏,通俗的講就是我們已經有一些有限個數的、排好序的桶子,將相應屬性的數據放入對應的桶中,再按桶的順序取出,新的數組就是有序的了。

桶排序的侷限性??

當我們選擇的數據範圍比較小時,例如人的身高、考試分數、績效評級,數據基本上處在一個小的數值範圍內,但當我們對員工薪資進行排序時,數據範圍很大從幾千到幾萬的都有,需要的桶的數量非常多,且當這些數據分佈不均勻時,會造成很大的空間浪費。

計數排序

基於桶排序思想,但是每個桶只存儲單一鍵值。比如過我們要把公司員工安裝身高進行排序,分析一個成年人的身高是在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]))

推薦閱讀:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章