基數排序(Radix Sort)是一種非比較型的整數排序算法,它的核心思想是按照數字的每一位(從最低位到最高位,例如個位、十位、百位等)依次進行排序。與基於比較的排序算法(如快速排序、歸併排序)不同,基數排序通過“分桶”和“收集”的方式實現排序,特別適合處理整數排序問題。

基數排序的基本思路

要使用基數排序,我們需要先確定待排序數組中最大數的位數,例如數組中的最大數是802,它有3位(個位、十位、百位),那麼我們就需要對這3位分別進行排序。具體步驟如下:

  1. 確定位數:找到數組中的最大數,計算其位數(例如802的位數是3)。
  2. 按位排序:從最低位(個位,第0位)開始,依次到最高位(百位,第2位)。對於每一位,我們將數組中的元素按照當前位的數字分到不同的“桶”中,然後按順序收集這些桶中的元素,完成該位的排序。
  3. 重複處理:對每一位重複上述分桶和收集操作,直到所有位都處理完畢,數組即完成排序。

Python實現步驟

下面我們通過代碼實現基數排序,關鍵步驟如下:

def radix_sort(arr):
    # 處理空數組情況
    if not arr:
        return arr

    # 找到數組中的最大數,確定需要排序的位數
    max_num = max(arr)
    digits = len(str(max_num))  # 最大數的位數,例如max_num=802時,digits=3

    # 遍歷每一位(從最低位到最高位,digit從0開始)
    for digit in range(digits):
        # 初始化10個桶(0-9),每個桶用於存放當前位數字相同的元素
        buckets = [[] for _ in range(10)]

        # 按當前位的數字將元素分到對應的桶中
        for num in arr:
            # 獲取當前位的數字:(num // 10^digit) % 10
            current_digit = (num // (10 ** digit)) % 10
            buckets[current_digit].append(num)

        # 將所有桶中的元素按順序收集,更新數組爲當前位排序後的結果
        arr = []
        for bucket in buckets:
            arr.extend(bucket)

    return arr

代碼解釋

  1. 處理空數組:如果輸入數組爲空,直接返回空數組,避免後續計算錯誤。
  2. 確定位數:通過max(arr)找到最大數,再用len(str(max_num))計算其位數(例如802的位數是3)。
  3. 分桶與收集
    - 初始化桶:創建10個空列表(對應0-9的數字),用於存放每一位排序後的元素。
    - 按位分桶:遍歷數組中的每個數,通過(num // (10 ** digit)) % 10獲取當前位數字(例如170的第0位(個位)是170//1 %10=0,第1位(十位)是170//10 %10=7),並將數放入對應桶中。
    - 收集元素:將所有桶中的元素按順序連接,得到當前位排序後的數組,作爲下一位排序的輸入。

測試示例

以數組[170, 45, 75, 90, 802, 24, 2, 66]爲例驗證算法:
1. 處理個位(第0位):所有數的個位數字爲0,5,5,0,2,2,4,6,分桶後收集結果爲[170, 90, 802, 2, 24, 45, 75, 66]
2. 處理十位(第1位):所有數的十位數字爲7,9,0,0,2,4,7,6,分桶後收集結果爲[802, 2, 24, 45, 66, 170, 75, 90]
3. 處理百位(第2位):所有數的百位數字爲8,0,0,0,0,1,0,0,分桶後收集結果爲[2, 24, 45, 66, 75, 90, 170, 802],排序完成。

總結

基數排序通過按位分桶和收集實現排序,時間複雜度爲O(d×(n+k))(其中d是最大數的位數,n是數組長度,k是桶的數量,此處k=10),空間複雜度爲O(n+k)。它特別適合處理位數較少的整數數組,尤其當數組中存在重複數字時效率更高。如果需要處理負數,可先將負數轉爲正數,排序後再恢復符號。

小夜