链表中基数排序

来源:互联网 发布:python 字典值为空 编辑:程序博客网 时间:2024/06/10 01:10

于两两比较的算法,算法的运行下界为Ω(nlogN),如果想再降低时间复杂度,只能通过其他的非基于比较的方法。基数排序就是一种方法,其时间复杂度为O(N)


基数排序的过程,假设有4个数,我们用链表把他们连一起,这4个数为

321  892   538  439

第一步:我们先创建10个链表,L0~L9,然后按4个数的个位的数字,依次接到相应链表的后面

L0 

L1     321

L2     892

L3

L4

L5

L6

L7

L8    538

L9    439

第二步:按连接在链表从L0~L9的数字,我们依照先后顺序,重新生成一个新的链表  

321  892 538 439

然后根据各个数的十位数,我们重新把他们连接到各个链表后面

L0 

L1     

L2     321

L3     538   439

L4

L5

L6

L7

L8    

L9    892

第三步:按连接在链表从L0~L9的数字,我们依照先后顺序,重新生成一个新的链表  

321  538 439 892

然后根据各个数的百位数,我们重新把他们连接到各个链表后面

L0 

L1     

L2     

L3     321

L4     439

L5     538

L6

L7

L8    892

L9   

总结步:按连接在链表从L0~L9的数字,我们依照先后顺序,重新生成一个新的链表  

321  439 538 892

至此,排序结果完成



完整代码如下:

(使用单链表实现的)

[cpp] view plain copy
  1. #include<iostream>  
  2. using namespace std;  
  3.   
  4. typedef  struct Node  
  5. {  
  6.     int data;  
  7.     struct Node *next;  
  8. }LNode;  
  9.   
  10. void Initiate(LNode **head)  
  11. {  
  12.     (*head)=(LNode*)malloc(sizeof(LNode));  
  13.     (*head)->next=NULL;  
  14. }  
  15.   
  16. void Insert(LNode *head,int num)  
  17. {  
  18.     if(head==NULL) return;  
  19.     else  
  20.     {  
  21.         LNode *p,*q;  
  22.         q=head;  
  23.         p=(LNode *)malloc(sizeof(LNode));  
  24.         p->data=num;  
  25.         p->next=NULL;  
  26.         while(q->next!=NULL)  
  27.         {  
  28.             q=q->next;  
  29.         }  
  30.         q->next=p;  
  31.     }  
  32. }  
  33.   
  34. LNode * GetFirstNode(LNode *head)  
  35. {  
  36.     if(head->next==NULL)  return NULL;  
  37.     else  
  38.     {  
  39.         LNode *p;  
  40.         p=head->next;  
  41.         head->next=p->next;  
  42.         return p;  
  43.     }  
  44. }  
  45.   
  46. void AppendNode(LNode *head,LNode *node)  
  47. {  
  48.     if(head==NULL) return;  
  49.     else  
  50.     {  
  51.         LNode *p;  
  52.         p=head;  
  53.         while(p->next!=NULL)  
  54.         {  
  55.             p=p->next;  
  56.         }  
  57.         p->next=node;  
  58.         node->next=NULL;  
  59.     }  
  60. }  
  61.   
  62. void Total(LNode *L,LNode *head)  
  63. {  
  64.     LNode *p;  
  65.     p=L;  
  66.     while(p->next!=NULL)  
  67.     {  
  68.         p=p->next;  
  69.     }  
  70.     p->next=head->next;  
  71. }  
  72.   
  73. int Power(int a,int n)  
  74. {  
  75.     int y;  
  76.     if(n==0)  
  77.         return 1;  
  78.     else  
  79.     {  
  80.         y=Power(a,n/2);  
  81.         y=y*y;  
  82.         if(n%2==1)  
  83.             y=y*a;  
  84.     }  
  85.     return y;  
  86. }  
  87.   
  88. int GetNum(LNode *p,int i)  
  89. {  
  90.     int data=p->data;  
  91.     int a;  
  92.     i--;  
  93.     a=data/Power(10,i);  
  94.     return a%10;  
  95. }  
  96. //第二个形参表示参加排序的整数最大位数一共有count位数字  
  97. void radix_sort(LNode *head,int count)  
  98. {  
  99.     LNode *p[10],*q;  
  100.     int i,j,k;  
  101.   
  102.     for(j=1;j<=count;j++)  
  103.     {  
  104.     //十个头结点初始化  
  105.     for(i=0;i<10;i++)  
  106.     {  
  107.         Initiate(&p[i]);  
  108.     }  
  109.     //链表从头到尾扫描,并将扫描到的节点脱离链表。  
  110.     while(head->next!=NULL)  
  111.     {  
  112.         q=GetFirstNode(head);  
  113.         k=GetNum(q,j); //取得链表节点第j位的元素值k  
  114.         AppendNode(p[k],q); //将该节点连接到10个链表相应的位置  
  115.     }  
  116.     //将10个链表从0-9依次连接到head节点后面  
  117.     for(i=0;i<10;i++)  
  118.     {  
  119.         Total(head,p[i]);  
  120.     }  
  121.     }  
  122.   
  123.     for(i=0;i<10;i++)  
  124.     {  
  125.         delete(p[i]);  
  126.     }  
  127.   
  128.   
  129. }  
  130.   
  131. void printSL(LNode *head)  
  132. {  
  133.     LNode *p;  
  134.     p=head->next;  
  135.     while(p!=NULL)  
  136.     {  
  137.         cout<<p->data<<" ";  
  138.         p=p->next;  
  139.     }  
  140. }  
  141.   
  142. void main()  
  143. {  
  144.     LNode *head;  
  145.     Initiate(&head);  
  146.     Insert(head,1113);  
  147.     Insert(head,4212);  
  148.     Insert(head,1232);  
  149.     Insert(head,6533);  
  150.     Insert(head,2332);  
  151.     Insert(head,123);  
  152.     Insert(head,23);  
  153.     radix_sort(head,4); //表示参加排序的整数最大位数一共有4位数字  
  154.     printSL(head);  
  155.     system("pause");  
  156. }  


附上使用双向链表实现的代码:

[cpp] view plain copy
  1. #include<iostream>  
  2. #include<assert.h>  
  3. using namespace std;  
  4.   
  5. int power(int a,int n)  //使用递归,O(logn),求a的n次方  
  6. {  
  7.     int y;  
  8.     if(n==0) return 1;  
  9.     else   
  10.     {  
  11.         y=power(a,n/2);  
  12.         y=y*y;  
  13.         if(n%2!=0)  
  14.             y=a*y;  
  15.     }  
  16.     return y;  
  17. }  
  18.   
  19. typedef struct Node  
  20. {  
  21.     int key;  
  22.     struct Node * prior;  
  23.     struct Node * next;  
  24. }SLnode;  
  25.    
  26. SLnode * create(int n)  
  27. {  
  28.     SLnode *head,*p,*q;  
  29.     int i;  
  30.     if((head=(SLnode *) malloc (sizeof(SLnode)))==NULL)  
  31.     {  
  32.         cout<<"error";  
  33.         exit(0);//创建失败则退出  
  34.     }  
  35.     head->prior=head;  
  36.     head->next=head;  
  37.     q=head;  
  38.     for(i=0;i<n;i++)  
  39.     {  
  40.         p=(SLnode *) malloc (sizeof(SLnode));  
  41.         assert(p!=NULL);//使用断言  
  42.         cin>>p->key;  
  43.         p->prior=q;  
  44.         q->next=p;  
  45.         q=p;  
  46.     }  
  47.     head->prior=q;  
  48.     q->next=head;  
  49.     return head;  
  50. }  
  51.   
  52. void printSL(SLnode *head)  
  53. {  
  54.     SLnode *p;  
  55.     p=head->next;  
  56.     while(p!=head)  
  57.     {  
  58.         cout<<p->key<<"  ";  
  59.         p=p->next;  
  60.   
  61.     }  
  62. }  
  63.   
  64. SLnode * GetFirstNode(SLnode *head)  
  65. {  
  66.     SLnode *p;  
  67.     p=head->next;  
  68.     if(p!=head)  
  69.     {  
  70.         p->next->prior=p->prior;  
  71.         p->prior->next=p->next;  
  72.     }  
  73.     else p=NULL;  
  74.     return p;  
  75. }  
  76.   
  77. int get_num(SLnode *p,int i)  //得到第i个数  
  78. {  
  79.     int key=p->key,num;  
  80.     num=key/power(10,i);  
  81.     return num%10;  
  82. }  
  83.   
  84. void addNode(SLnode *head,SLnode *p)  
  85. {  
  86.     p->prior=head->prior;  
  87.     p->next=head;  
  88.     head->prior->next=p;  
  89.     head->prior=p;  
  90. }  
  91.   
  92. void append(SLnode *head,SLnode *Lhead)  
  93. {  
  94.     if(Lhead->next!=Lhead)  //这个判断条件一定要写上,  
  95.     {  
  96.     Lhead->next->prior=head->prior;  
  97.     Lhead->prior->next=head;  
  98.     head->prior->next=Lhead->next;  
  99.     head->prior=Lhead->prior;  
  100.     }  
  101. }  
  102.   
  103.   
  104. void radix_sort(SLnode *head,int n)  //实习基数排序  
  105. {  
  106.     SLnode *Lhead[10],*p;  
  107.     int i,j,k,f;  
  108.     for(i=0;i<10;i++)  
  109.     {  
  110.         Lhead[i]=(SLnode *)malloc(sizeof(SLnode));  
  111.         assert(Lhead[i]!=NULL);  
  112.     }  
  113.       
  114.     for(i=0;i<n;i++)  
  115.     {  
  116.         for(k=0;k<10;k++)  
  117.         {  
  118.             Lhead[k]->next=Lhead[k];  
  119.             Lhead[k]->prior=Lhead[k];  
  120.         }  
  121.         while(head->next!=head)  
  122.         {  
  123.         p=GetFirstNode(head);//get first Node,and delete it  
  124.         j=get_num(p,i);//得到第i个数  
  125.         addNode(Lhead[j],p);//将取得的节点连接到Lhead[j]后面  
  126.         }  
  127.   
  128.         for(f=0;f<10;f++)  
  129.           append(head,Lhead[f]);  
  130.     }  
  131.   
  132.      for(i=0;i<10;i++)//删除节点  
  133.         delete(Lhead[i]);  
  134.   
  135. }  
  136.   
  137. void main()  
  138. {  
  139.     int a,b;  
  140.     SLnode *head;  
  141.     cin>>a;  
  142.     head=create(a);  
  143.     printSL(head);  
  144.     cout<<endl;  
  145.     cout<<"weishu"<<endl; //输入所要比较的数字的位数  
  146.     cin>>b;  
  147.      radix_sort(head,b);  
  148.     printSL(head);  
  149.     system("pause");  
  150. }  
0 0
原创粉丝点击