基數排序

基數排序的思想整體上就是把一組數中的全部數按照個十百位來改變在數組中的位置,分配十個桶(存放數的容器)對應0~9。好比在比較個位數時,把個位數爲0的全部數放在第一個桶內,個位數爲1的數放在第二個桶內,依次放入。在全部的數放完以後,此時數組內的數已經改變了位置,再比較十位數,重複上述操做,直到最大位數。node

 

 

 

經過三次存入桶的操做後,全部的數變有序了。若是數中還有千位,則應該還要操做一次。即對應數有多少位來進行操做。數組

 

代碼中使用鏈式隊列來做爲桶,由於不知道一個桶內要存放多少數。spa

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #define M 3                        //定義一個數最多隻有三位 
  4 #define RAX 10                    //定義十個桶 
  5 
  6 typedef struct node{            //每一個節點中都要一個數 
  7     int key[M];                    //這個數組是存放一個數的個十百位上的數 
  8     struct node *next;            //每一個桶都是一個鏈隊列 
  9 }Rnode; 
 10 
 11 Rnode *f[RAX],*r[RAX];            //f是隊列的頭指針,r是隊列的尾指針 
 12 
 13 //給每一個鏈隊列分配空間 
 14 void initBarrel(Rnode *f[RAX],Rnode *r[RAX]){
 15     int i;
 16     for(i=0;i<RAX;i++){
 17         f[i] = (Rnode *)malloc(sizeof(Rnode));
 18         r[i] = (Rnode *)malloc(sizeof(Rnode));
 19     }
 20 }
 21 
 22 //初始化一個鏈表 
 23 Rnode *setList(int num[],int n){
 24     
 25     Rnode *p,*head = (Rnode *)malloc(sizeof(Rnode));
 26     head->next = NULL;
 27     
 28     int i,j;
 29     for(i=0;i<n;i++){
 30         p = (Rnode *)malloc(sizeof(Rnode));
 31         p->key[0] = num[i]/100;                //把一個數的個十百位分別存放到數組中,百位在最前 
 32         p->key[1] = num[i]/10%10;            //十位在中間 
 33         p->key[2] = num[i]%10;                //個位在最後 
 34         p->next = head->next;                //此處使用頭插法,方便後面的操做 
 35         head->next = p;
 36     }
 37     
 38     return head;
 39     
 40 }
 41 
 42 //把數放入桶中 
 43 void distribute(Rnode *head,int n){
 44 //這個n就是指定了數的哪一個位數,假如是個位,就把數的個位與桶下標相同的這個數放入到那個桶裏去 
 45     int i,j;
 46     for(i=0;i<RAX;i++){                    //使每組 r[i]、f[i]做爲此組一個隊列的頭尾指針 
 47         r[i]->next = NULL;
 48         f[i] = r[i];
 49     }
 50     
 51     head = head->next;                    //此處要用兩個指針來取值 
 52     Rnode *p = head;
 53     
 54     while(p!=NULL){
 55         head = head->next;            //head指在p下一個位置,前面斷的部分影響不到head指針繼續日後走 
 56         j = p->key[n];                //根據這個節點中,數的個十百位來存放到指定的桶 
 57         r[j]->next = p;                //這裏是隊列的入隊操做 
 58         r[j] = p;                    
 59         r[j]->next = NULL;            //此時鏈表在p指針處已經斷了,由於p->next=NULL 
 60         p = head;                    //p指向head,繼續向後遍歷 
 61     }
 62     
 63 }
 64 
 65 //把桶裏的數拿出來 
 66 Rnode *collect(){
 67     
 68     Rnode *t,*p,*head = (Rnode *)malloc(sizeof(Rnode));
 69     head->next = NULL;
 70     
 71     int i,j;
 72     for(i=0;i<RAX;i++){                    //對每一個桶都要遍歷 
 73         t = f[i]->next;                    
 74         while(t!=NULL){                    //遍歷這個桶裏的全部數 
 75             p = (Rnode *)malloc(sizeof(Rnode));
 76             for(j=0;j<M;j++)
 77                 p->key[j] = t->key[j];
 78             
 79             p->next = head->next;        //把桶中的數取出存放到鏈表裏,存放方式仍是頭插法 
 80             head->next = p;
 81             t = t->next;
 82         }
 83     }
 84     return head;
 85 }
 86 
 87 void main(){
 88     
 89     int i,num[10] = {121,231,12,322,901,678,765,875,661,410};
 90     
 91     Rnode *p,*head = setList(num,10);
 92     
 93     initBarrel(f,r);                //給每一個鏈隊列分配空間 
 94     
 95     for(i=M-1;i>=0;i--){
 96         distribute(head,i);            //每次傳入不一樣的數,用於對數字的個十百位。 
 97         head = collect();            //把桶中的數取出存方法到鏈表裏,存放方式仍是頭插法 
 98     }
 99     
100     p = head->next;
101     while(p!=NULL){                    //其實打印的順序是反的,由於用的頭插法 
102         printf("%d%d%d ",p->key[0],p->key[1],p->key[2]);
103         p = p->next;
104     }
105 }
相關文章
相關標籤/搜索