基數排序 LSD py

沙滩炒花蛤發表於2024-04-27

連結:https://www.nowcoder.com/questionTerminal/1e68ccb2cbc74c3d9e0dea0c568789b8
設陣列S[]={154,265,146,31,213,14,157,189,91,10,111,123},採用最低位優先(LSD)基數排序將S排列成升序序列,第1趟分配收集後元素14之前,之後緊鄰的元素是()
第1趟分配收集後的結果為:10,31,91,111,213,123,154,14,265,146,157,189

基數排序可以排序整數、字元。原理是補齊長度,按位比較,按照比較方向可以分為低位優先(Least Significant Digit first, LSD)和高位優先 (MSD)。

平均時間複雜度:O(n*k),k是最大位數

原理

這裡以比較整形數字為例:

  1. 確定最大數的位數:首先找出待排序數中的最大數,以確定最大位數。
  2. 初始化桶:建立10個桶(0-9),每個桶用於存放對應位數的數字。
  3. 分配數字到桶:從 最低位/最高位 開始,遍歷每個數字,根據當前位的數值將其放入相應的桶中。
  4. 收集桶中數字:按順序收集桶中的數字,放回原陣列。
  5. 重複過程:對每一位重複上述分配和收集過程,直到 最高位/最低位。

低位優先

def radix_sort(arr):
    # 找出最大數以確定最大位數
    max_num = max(arr)
    # 計算最大數的位數
    max_digits = len(str(max_num))

    # 初始化桶
    buckets = [[] for _ in range(10)]

    # 從最低位開始,對每一位進行排序
    for digit in range(max_digits):
        # 分配數字到桶
        for num in arr:
            # 計算當前位的數值
            current_digit = (num // (10 ** digit)) % 10
            # 將數字放入相應的桶中,相同數字放在同一個桶,列表可以保證順序
            buckets[current_digit].append(num)

        # 收集桶中的數字,放回原陣列
        # arr = [num for bucket in buckets for num in bucket] #  不好理解
        arr.clear()
        for bucket in buckets:
            arr.extend(bucket)

        # 清空桶,為下一次分配做準備
        buckets = [[] for _ in range(10)]
        print(f"DEBUG digit: {digit}, arr: {arr}")

    return arr

# 測試陣列
arr = [154, 265, 146, 31, 213, 14, 157, 189, 91, 10, 111, 123]
# 執行基數排序
sorted_arr = radix_sort(arr)
# 列印排序後的陣列
print(sorted_arr)
DEBUG digit: 0, arr: [10, 31, 91, 111, 213, 123, 154, 14, 265, 146, 157, 189]
DEBUG digit: 1, arr: [10, 111, 213, 14, 123, 31, 146, 154, 157, 265, 189, 91]
DEBUG digit: 2, arr: [10, 14, 31, 91, 111, 123, 146, 154, 157, 189, 213, 265]
[10, 14, 31, 91, 111, 123, 146, 154, 157, 189, 213, 265]

refer

圖文總結」程式設計師必知必會的十大排序演算法 bigsai 發起於 2020-11-28

相關文章