看板 ott
作者 ott (寶貝)
標題 基數排序(Radix Sort)
時間 2013年08月19日 Mon. AM 09:19:43


       
     
   
 


http://notepad.yehyeh.net/Content/Algorithm/Sort/Radix/Radix.php

[演算法(Algorithm)] 基數排序(Radix Sort)






    	
  • 基數排序
    	
    	

      	
      	
      	
    • 又叫基底排序Bin SortBucket Sort

    • 	
      	
      	
    • 是一種分配式排序(Distribution Sort)

    • 	
      	
      	
    • 可以多鍵值排序
      	
      	
      	
      	

        	
        	
        	
        	
        	
      • 兩個鍵值:(1,2), (2,2), (3,1),...

      • 	
        	
        	
        	
        	
      • 撲克牌(花色、數值):(♠7), (7), (♣6), (3)

      • 	
        	
        	
        	

      	
      	
      	

    • 	
      	
      	
    • 只有一個鍵值時,可以利用分解鍵值來進行基數排序

    • 	
      	
      	
    • 數值切割以進行排序
      	
      	
      	
      	

        	
        	
        	
        	
        	
      • 92 = 9, 2

      • 	
        	
        	
        	
        	
      • 173 = 1, 7, 3

      • 	
        	
        	
        	

      	
      	
      	

    • 	
      	
      	
    • 利用桶子(Bucket)來分類

    • 	
      	
      	
    • 以r為基底(Base)時,需準備r個桶子  數值時,基底即為進制
      	
      	
      	
      	
      • 排序10進位數字,需10個桶子

      	
      	
      	

    • 	
      	
      	
    • 資料的位數即為執行的回合數
      	
      	
      	
      	

        	
        	
        	
        	
        	
      • 數值的範圍在0~9內,需執行1回合

      • 	
        	
        	
        	
        	
      • 數值的範圍在0~99內,需執行2回合

      • 	
        	
        	
        	
        	
      • 數值的範圍在0~999內,需執行3回合

      • 	
        	
        	
        	

      	
      	
      	

    • 	
      	

    	

  • 	
  • LSD & MSD
    	
    	

      	
      	
      	
    • LSD(Least Significant Digital)
      	
      	
      	
      	

        	
        	
        	
        	
        	
      • 由右到左

      • 	
        	
        	
        	
        	
      • 173,依序用3,7,1來分類

      • 	
        	
        	
        	

      	
      	
      	

    • 	
      	
      	
    • MSD(Most Significant Digital)
      	
      	
      	
      	
        	
        	
        	
        	
        	

        	
        	
        	
        	
        	
      • 由左到右

      • 	
        	
        	
        	
        	
      • 173,依序用1,7,3來分類

      • 	
        	
        	
        	

      	
      	
      	

    • 	
      	

    	

  • 	
  • 基數排序作法
    	
    	

           
    	
    	

               

               
    	

                 
      	
      	
    1. 選定好本回合使用的基數

    2. 	
      	
      	
      	
      	
    3. 依序用基數對每一筆資料取得該回合的LSD

    4. 	
      	
      	
      	
      	
    5. 依取得的LSD將資料放到對應的桶子

    6. 	
      	
      	
      	
      	
    7. 桶子內存放的順序,將資料回存原來的陣列

    8. 	
      	
      	
      	
      	
    9. 重複上面四個步驟,直到範圍內的基數皆已使用

    10. 	
      	
      	
      	

               
               

               
    	

                 
      	
      	
    1. 選定好本回合使用的基數

    2. 	
      	
      	
      	
      	
    3. 依序用基數對每一筆資料取得該回合的MSD

    4. 	
      	
      	
      	
      	
    5. 依取得的MSD將資料放到對應的桶子

    6. 	
      	
      	
      	
      	
    7. 依序對每個桶子重複上述三個步驟(遞迴),直到範圍內的基數皆已使用

    8. 	
      	
      	
      	
      	
    9. 桶子內存放的順序,將資料回存原來的陣列

    10. 	
      	
      	
      	

               
           
           
    	

  • 	
  • Radix Sort(LSD)圖解:
    	
    	

    	
    	
    	

    	
    	
    	
    	
    Radix Sort
    	
    	
    	
    	
    Radix Sort
    	
    	
    	
    	
    	
    	
  • 	
    	


    	
  • 時間複雜度(Time Complexity)
    	
    	

      	
      	
      	
    • Best Case:Ο(d × (n+r))

    • 	
      	
      	
    • Worst Case:Ο(d × (n+r))

    • 	
      	
      	
    • Average Case:Ο(d × (n+r))

    • 	
      	
      	
    • 說明:
      	
      	
      	
      	

        	
        	
        	
        	
        	
      • d = 執行回合數

      • 	
        	
        	
        	
        	
      • n = 數列長度

      • 	
        	
        	
        	
        	
      • r = 基數

      • 	
        	
        	
        	
        	
      • 每回合將資料分配到桶子需Ο(n)

      • 	
        	
        	
        	
        	
      • 每回合將桶子內的資料取出,合併成數列需Ο(r)

      • 	
        	
        	
        	
        	
      • ∴每回合需Ο( n + r)

      • 	
        	
        	
        	

      	
      	
      	

    • 	
      	
      	

      	
      	

    	

  • 	
  • 空間複雜度(Space Complexity):Ο(n × r)
    	
    	

      	
      	
      	
    • 使用二維陣列來當桶子:Ο(n × r)
      	
      	
      	
      	

        	
        	
        	
        	
        	
      • n = 數列長度

      • 	
        	
        	
        	
        	
      • r = 基數

      • 	
        	
        	
        	
        	
      • 需要r個桶子,每個桶子需可放n筆資料  Ο( n × r)

      • 	
        	
        	
        	
      	

      	
      	
      	

    • 	
      	
      	
    • 使用鏈結串列來當桶子:Ο(n)
      	
      	
      	
      	

        	
        	
        	
        	
        	
      • n = 數列長度

      • 	
        	
        	
        	

      	
      	
      	
    • 	
      	

      	
      	

    	

  • 	
  • 穩定性(Stable/Unstable):穩定(Stable)


  • 	
  • 演算法
    	
    	

           
    	
      	

                 
      	
    • JS(LSD)
    •            
      	
                 
             
      	
    	

               


    //初始化桶子
    var initArray = function(buckets, count){
        for(var i = 0; i < buckets.length; i++){
            buckets[i]  = new Array(buckets.length);
            count[i] = 0;
        }
    }

    var radixSort = function(data){
        var MAX = 100;                          // 數的上限
        var dataIndex = 0, radix = 1;           // radix = 1, 10, 100,...
        var buckets = new Array(data.length),   // 桶子
            count = new Array(data.length);     // 記錄每個桶子裝了幾個數值
        initArray( buckets, count );            // 初始化桶子

        while(radix <= MAX){                    // 若基數沒有超出上限
       
    	
    // 分配
            for(var i = 0; i < data.length; i++){
                var LSD = parseInt((data[i]/radix)) % 10;    // 計算LSD(=那一個桶子)
                buckets[LSD][count[LSD]] = data[i];          // 將資料放到對應的桶子
                count[LSD]++;
            }
            radix *= 10;                                     // 更新基底:1->10, 10->100
    	
    	

            // 合併
            dataIndex = 0;
            for(var i = 0; i < data.length; i++){         // 將桶子內的資料合併
                if(count[i] != 0){                        // 如果桶子內有資料
                    for(var j =0 ; j < count[i]; j++){
                        data[dataIndex++] = buckets[i][j];
                    }
                }
                count[i] = 0;                             // 歸0,以便下一回合使用
            }
    	
    	

        }
    };

    radixSort(data);
       
               
       
    	
    	
    	
    	
    	
  •    
    	

    	


    	




 

 
 
※ 編輯: ott 時間: 2013-08-19 09:31:14
※ 看板: ott 文章推薦值: 0 目前人氣: 0 累積人氣: 485 
分享網址: 複製 已複製
guest
x)推文 r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇