連結: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是最大位數
原理
這裡以比較整形數字為例:
- 確定最大數的位數:首先找出待排序數中的最大數,以確定最大位數。
- 初始化桶:建立10個桶(0-9),每個桶用於存放對應位數的數字。
- 分配數字到桶:從 最低位/最高位 開始,遍歷每個數字,根據當前位的數值將其放入相應的桶中。
- 收集桶中數字:按順序收集桶中的數字,放回原陣列。
- 重複過程:對每一位重複上述分配和收集過程,直到 最高位/最低位。
低位優先
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