码迷,mamicode.com
首页 > 编程语言 > 详细

基数排序 <最低位优先> 链表实现

时间:2017-12-23 16:02:50      阅读:309      评论:0      收藏:0      [点我收藏+]

标签:序列   type   复杂度   next   its   span   思路   ret   效果   

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.没懂的地方请在下边评论区留言,我会尽量为大家解答的。。。希望大家支持

基数排序 <最低位优先> 链表实现

标签:序列   type   复杂度   next   its   span   思路   ret   效果   

原文地址:http://www.cnblogs.com/qianyu30254/p/8093198.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!