圖解基數排序(Radix Sort)

基數排序(Radix Sort)

基數排序是一種非比較型整數排序算法,其原理是將整數按位數切割成不同的數字,然後按每個位數分別比較。由於整數也可以表達字符串(比如名字或日期)和特定格式的浮點數,所以基數排序也不是隻能使用於整數。

基數排序是按照低位先排序,然後收集;再按照高位排序,然後再收集;依次類推,直到最高位。有時候有些屬性是有優先級順序的,先按低優先級排序,再按高優先級排序。最後的次序就是高優先級高的在前,高優先級相同的低優先級高的在前。

算法描述

  • 取得數組中的最大數,並取得位數;
  • arr爲原始數組,從最低位開始取每個位組成radix數組;
  • 對radix進行計數排序(利用計數排序適用於小範圍數的特點);

動圖演示

 

代碼實現

int get_digit(int x, int i) {
    while (--i) x /= 10;
    return x % 10;
}

// 基數排序 需要知道整數的最大位數digits是多少 
void radix_sort(vector<int> &v, const int &digits) {
    vector<vector<int>> buckets(10);
    int size = v.size();

    for (int i = 1; i <= digits; ++i) {
        for (int j = 0; j < 10; ++j) { buckets[j].clear(); }

        for (int j = 0; j < size; ++j) {
            buckets[get_digit(v[j], i)].push_back(v[j]);
        }

        for(int j = 0, k = 0; j < 10; ++j)
            for(int e : buckets[j])
                v[k++] = e;
    }
}

算法分析

基數排序基於分別排序,分別收集,所以是穩定的。但基數排序的性能比桶排序要略差,每一次關鍵字的桶分配都需要O(n)的時間複雜度,而且分配之後收集得到新的關鍵字序列又需要O(n)的時間複雜度。假如待排數據可以分爲d個關鍵字,則基數排序的時間複雜度將是O(d*2n) ,當然d要遠遠小於n,因此基本上還是線性級別的。基數排序的空間複雜度爲O(n+k),其中k爲桶的數量。一般來說n>>k,因此額外空間需要大概n個左右。

基數排序 vs 計數排序 vs 桶排序

這三種排序算法都利用了桶的概念,但對桶的使用方法上有明顯差異:

  • 基數排序:根據鍵值的每位數字來分配桶;
  • 計數排序:每個桶只存儲單一鍵值;
  • 桶排序:每個桶存儲一定範圍的數值;

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