1. 程式人生 > >基數排序 <最低位優先> 鏈表實現

基數排序 <最低位優先> 鏈表實現

數據 節點 基數排序 class 初始 %d fine namespace 結束

1.單刀直入

  基數排序是基於多關鍵字的一種排序,借助“分配”與“收集”兩個過程來得到一個有序序列,其時間復雜度為O(d(n+rd)),空間復雜度為O(n+rd),屬於穩定的排序...

  舉個例子,加入有一下待排序列#->278->109->63->930->589->184->505->269->8->83(#為頭節點,其他為數據節點)

  依次序列,我們可以容易得到一下信息:

         rd:rd在這裏指的是十進制的十,即rd = 10(but,如果是在一字母序列中,例如#->‘C‘->‘A‘->‘B‘->‘F‘這裏rd指的就是二十六進制,即rd = 26)

         d: d在這裏指的是序列中最大值的位數,很容易得到此序列中的最大值為930,是一個三位數,即d = 3

2.過程簡介

  接上,待排序列為:

  #->278->109->63->930->589->184->505->269->8->83

  接下來,我們就需開始進行第一趟分配(按個位分配),建立是rd個隊列或者是rd個鏈表(以下前面的0,1,2.。。。9都是鏈表序號):

  註意:按個位分配的意思就是:例如278的個位就是8,就把它放入第8號鏈表;109的個位是9,就把它放入第9號鏈表;依次類推。。。

  0->930

  1

  2

  3->63->83

  4->184

  5->505

  6

  7

  8->278->8

  9->109->589->269

  分配後,開始第一趟收集(這裏收集就是從0號鏈表開始收集到9號鏈表結束):

  #->930->63->83->184->505->278->8->109->589->269

  第二趟分配(按十位分配):

  0->505->109->8

  1

  2

  3->930

  4

  5

  6->63->269

  7->278

  8->83->184->589

  9

  第二趟收集:

  #->505->109->8->930->63->269->278->83->184->589

  第三趟分配(按百位分配):

  0->8->63->83

  1->109->184

  2->269->278

  3

  4

  5->505->589

  6

  7

  8

  9->930

  第三次收集:

  #->8->63->83->109->184->269->278->505->589->930

  排序完成。。。

3.其實思路就是那樣,不過代碼因人而異,拿什麽數據結構去實現就可以達到不同的效果,但結果都可以使之有序,下面給出參考代碼

  1 #include <bits/stdc++.h>
  2 #define SIZE 0x32
  3 #define rd 10
  4 using namespace std;
  5 typedef struct snode{
  6     int key;
  7     struct snode* next;//下位指針
  8 } *sRadix;
  9 typedef struct bnode{
 10     sRadix d[SIZE];//最大長度
 11     int length;//實際長度
 12 } bRadix;
 13 int a[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};//輔助下標數組
 14 int getPos(int value, int pos);//獲得下標
 15 void radixSort(bRadix &rl);//基數排序
 16 void printL(bRadix rl);//打印收集鏈表
 17 void printC(bRadix r);//打印分配過程
 18 int main(){
 19     bRadix rl;//收集主鏈表
 20     bRadix la;//運動鏈表
 21     cout << "- - - - - - - - -1.基數排序- - - - - - - - -\n";
 22     cout << "請輸入需排序的序列的長度:\n";
 23     cin >> rl.length;
 24     cout << "初始化收集表...";
 25     rl.d[rl.length] = new snode;
 26     rl.d[rl.length]->next = NULL;
 27     la = rl;
 28     cout << "請輸入序列的元素集合:\n";
 29     for(int i = 0; i < rl.length; i++){//初始化收集鏈表
 30         sRadix p = new snode;
 31         cin >> p->key;
 32         p->next = la.d[rl.length]->next;
 33         la.d[rl.length]->next = p;
 34         la.d[rl.length] = p;
 35     }
 36     radixSort(rl);
 37     cout << "進過排序後的序列如下...\n";
 38     printL(rl);
 39     return 0;
 40 }
 41 int getPos(int value, int pos){
 42     return value / a[pos - 1] % 10;
 43 }
 44 void radixSort(bRadix &rl){
 45     int maxValue = 0, d = 1;
 46     bRadix r;
 47     r.length = rl.length;
 48     r.d[r.length] = rl.d[rl.length];
 49     while(r.d[rl.length]->next){
 50         if(r.d[rl.length]->next->key > maxValue)
 51             maxValue = r.d[rl.length]->next->key;
 52         r.d[rl.length] = r.d[rl.length]->next;
 53     }
 54     for(int i = 1; i < rd; i++)
 55         if(maxValue / a[i] == 0) break;
 56         else d++;
 57     for(int i = 1; i <= d; i++){
 58         printf("- - - - - - - - -第%d次分配- - - - - - - - -\n", i);
 59         bRadix r2, r0;
 60         r0.length = r2.length = rl.length;
 61         r0.d[r0.length] = r2.d[r2.length] = rl.d[rl.length];
 62         for(int k = 0; k < rl.length; k++){
 63             r0.d[k] = r2.d[k] = new snode;
 64             r0.d[k]->next = r2.d[k]->next = NULL;
 65         }
 66         while(r0.d[r0.length]->next){
 67             int key = r0.d[rl.length]->next->key;
 68             int pos = getPos(key, i);
 69             for(int j = 0; j < rd; j++){
 70                 if(pos == j){
 71                     sRadix p = new snode;
 72                     p->key = key;
 73                     p->next = r0.d[j]->next;
 74                     r0.d[j]->next = p;
 75                     r0.d[j] = p;
 76                     j = rd;
 77                 }
 78             }
 79             r0.d[r0.length] = r0.d[r0.length]->next;
 80         }
 81         printC(r2);
 82         for(int j = 0; j < rd; j++){
 83             if(r2.d[j]){
 84                 while(r2.d[j]->next){
 85                     int key = r2.d[j]->next->key;
 86                     r2.d[rl.length]->next->key = key;
 87                     r2.d[j] = r2.d[j]->next;
 88                     r2.d[rl.length] = r2.d[rl.length]->next;
 89                 }
 90             }
 91         }
 92     }
 93     cout << "- - - - - - - - -排序結束- - - - - - - - -\n";
 94 }
 95 void printL(bRadix rl){
 96     while(rl.d[rl.length]->next){
 97         cout << rl.d[rl.length]->next->key << " ";
 98         rl.d[rl.length] = rl.d[rl.length]->next;
 99     }
100     cout << endl;
101 }
102 void printC(bRadix r){
103     for(int i = 0; i < rd; i++){
104         printf("#(%d)", i);
105         if(r.d[i]){
106             while(r.d[i]->next){
107                 cout << "->" << r.d[i]->next->key;
108                 r.d[i] = r.d[i]->next;
109             }
110         }
111         cout << endl;
112     }
113 }

效果圖如下(包含上述分配與收集過程):

技術分享圖片

4.沒懂的地方請在下邊評論區留言,我會盡量為大家解答的。。。希望大家支持

基數排序 <最低位優先> 鏈表實現