基數排序 是非比較型整數排序算法,時間複雜度 O(d·(n+k)) (d=位數, n=元素數, k=基數),適合大量整數排序。本文展示 Python 純實現、效能基準測試、與內建 sorted() 比較、適用場景與優化方向。
d。
def radix_sort(arr: list[int]) -> list[int]:
"""基數排序 (LSD),原地修改並回傳列表"""
if not arr:
return arr
# 1. 找最大值決定輪數
max_val = max(arr)
exp = 1 # 10^0, 10^1, ...
# 2. 處理負數:分離負數與非負數,負數取絕對值排序後反轉
neg = [x for x in arr if x < 0]
non_neg = [x for x in arr if x >= 0]
def _radix_sort_non_neg(nums):
if not nums:
return nums
max_num = max(nums)
exp = 1
while max_num // exp > 0:
buckets = [[] for _ in range(10)]
for num in nums:
digit = (num // exp) % 10
buckets[digit].append(num)
# 合併桶
nums[:] = [num for bucket in buckets for num in bucket]
exp *= 10
return nums
sorted_neg = _radix_sort_non_neg([-x for x in neg])[::-1] # 反轉並加負號
sorted_neg = [-x for x in sorted_neg]
sorted_non_neg = _radix_sort_non_neg(non_neg)
arr[:] = sorted_neg + sorted_non_neg
return arr
def radix_sort_simple(arr):
"""假設所有元素 >= 0"""
if not arr:
return arr
max_val = max(arr)
exp = 1
while max_val // exp > 0:
buckets = [[] for _ in range(10)]
for num in arr:
buckets[(num // exp) % 10].append(num)
arr[:] = [num for bucket in buckets for num in bucket]
exp *= 10
return arr
import random, time
def benchmark():
sizes = [10_000, 100_000, 1_000_000]
for n in sizes:
data = [random.randint(0, 10**9) for _ in range(n)]
# Python 內建 Timsort
t0 = time.perf_counter()
sorted_builtin = sorted(data)
t1 = time.perf_counter()
print(f"n={n:,} sorted(): {(t1-t0)*1000:.1f} ms")
# 基數排序
data_copy = data[:]
t0 = time.perf_counter()
radix_sort_simple(data_copy)
t1 = time.perf_counter()
print(f"n={n:,} radix_sort: {(t1-t0)*1000:.1f} ms")
assert data_copy == sorted_builtin
print()
if __name__ == '__main__':
benchmark()
n=10,000 sorted(): 2.1 ms n=10,000 radix_sort: 8.5 ms n=100,000 sorted(): 24.3 ms n=100,000 radix_sort: 82.7 ms n=1,000,000 sorted(): 285 ms n=1,000,000 radix_sort: 920 ms
| 因素 | 內建 sorted() | 純 Python 基數排序 |
|---|---|---|
| 實現層級 | C 層 (Timsort) | Python 位元組碼解釋執行 |
| 記憶體存取 | 連續陣列操作、高度優化 | 列表推導式、多層巢狀迴圈、頻繁建立桶列表 |
| 比較次數 | O(n log n) 比較 | O(d·n) 整數運算,無比較 |
| 常數因子 | 極低 | 高 (Python 迴圈開銷大) |
| 場景 | 推薦方案 | 理由 |
|---|---|---|
| 一般用途、資料量 < 100萬 | sorted() / list.sort() | 內建最快、支援任意可比較物件、穩定 |
| 大量非負整數 (億級)、固定位數 | NumPy + argsort 或 Numba | 向量化/JIT 逼近 C 效能 |
| 嵌入式/無依賴環境、教學展示 | 純 Python 實現 | 零依賴、邏輯清晰 |
| 字串/定長鍵排序 | 基數排序擴展 (LSD/MSD) | 同樣原理適用字元編碼 |
O(n+k) 額外空間 (桶 + 輸出陣列),非原地演算法。基數排序是理解「非比較排序」的經典範例,但在 Python 實務中,**優先使用內建 sorted()**;極大規模整數排序才考慮 NumPy/Numba 加速版本。