排序算法-----基数排序

来源:互联网 发布:jquery 判断数组为空 编辑:程序博客网 时间:2024/05/17 06:34
#include<stdio.h>#include<stdlib.h>#define MAX_NUM_KEY 8#define PADIX  10#define MAX_SPACE  12typedef struct{  int  key[MAX_NUM_KEY];//关键字------但是这个我却没有用到  int  otheritems;  //其他项 也就是具体的数  int next; //指向静态链表的下一项}SLCell;typedef struct{  SLCell r[MAX_SPACE];  //静态链表的空间,r[0]为头结点  int keynum;          //静态链表的关键字的个数  int recnum;        //静态链表的当前长度}SLList;typedef int arrtype[PADIX];  //定义的指针数组void inital(SLList &l){      //初始化l.r[1].otheritems=278;l.r[2].otheritems=109;l.r[3].otheritems=63;  //用数字给一个变量赋值时如果前面是有0的,比如063,008它会默认这个是八进制的数字,不是十进制l.r[4].otheritems=930;l.r[5].otheritems=589;l.r[6].otheritems=184;l.r[7].otheritems=505;l.r[8].otheritems=269;l.r[9].otheritems=8;  //用数字给一个变量赋值时如果前面是有0的,比如063,008它会默认这个是八进制的数字,不是十进制l.r[10].otheritems=83; //用数字给一个变量赋值时如果前面是有0的,比如063,008它会默认这个是八进制的数字,不是十进制l.recnum=10;l.keynum=3;}int ord(int i,int j)  //取r[p].otheritems这个数的第i位是什么数字{int k,m,l;    int a[10];for(k=0;k<3;k++) //因为例子都是三位的数字所以k遍历3次{m=i%10;//这个道理很简单,想要取到某一位,比如685这个数字685%10得5就得到了685的个位数i=i/10;//  685/10得68  然后第二轮再经上一步可以得到十位数,以此类推a[k]=m;//将位数付给一个数组}l=a[j];//根据要求取哪位,就从数组中取出来return l;}void Distribute(SLCell r[],int i,arrtype &f,arrtype &e){   //分配函数 f指向该列的第一个记录,e指向该列最后一个记录(按照第i个记录来分配)   int j,p;   for(j=0;j<PADIX;j++) f[j]=0;  //将各个子表初始化   for(p=r[0].next;p;p=r[p].next){  //依次将所有的记录求得第i个关键字,分别放到子表中去   j=ord(r[p].otheritems,i);  //取r[p].otheritems这个数的第i位是什么数字,再赋值给j   if(!f[j])   f[j]=p;  //如果在j这个子表中还没有记录,就将数组下标p付给f[j]做该列的第一个记录   else r[e[j]].next=p;//如果j这个子表中之前已经有记录了,把p付给在同一列的最后一个记录的下一个   e[j]=p; //把p作为j列的最后一个记录   }}void Collect(SLCell r[],int i,arrtype &f,arrtype &e){  //收集函数 从分配好的子表中把他们再串起来   int j,t;   for(j=0;!f[j];j++); //找到第一个有记录的表   r[0].next=f[j]; t=e[j]; //表中第一个记录付给r[0].next,最后一个记录用t来记录   while(j<PADIX-1)   {   for(j++;!f[j]&&j<PADIX-1;j++);  //找到有记录的表   if(f[j])   {r[t].next=f[j]; t=e[j];} //有记录的表,将该表第一个记录付给上一个表的最后一个记录的next,再把这个表的最后一个用t记录   }   r[t].next=0; //表尾要用0表示}void RadixSort(SLList &l) //基数排序主函数{   int i,j;   int f[PADIX],e[PADIX]; //两个指针变量     for(i=0;i<l.recnum;i++)     l.r[i].next=i+1;     l.r[l.recnum].next=0;  //将l变成静态链表   for(i=0;i<l.keynum;i++)   {   Distribute(l.r,i,f,e);//第i趟分配   Collect(l.r,i,f,e);   //第i趟收集   }}void  print(SLList l){int i,j;i=l.r[0].next;for(j=0;j<l.recnum;i=l.r[i].next,j++){printf("%d   ",l.r[i].otheritems);}}void main(){SLList l;inital(l);RadixSort(l);print(l);getchar();getchar();}//算法分析:1.对于n个记录(每个记录有d个关键字,每个关键字的取值范围为rd个值)进行排序的时间复杂度为O(d(n+rd))(每一趟分配的时间复杂度为O(n)收集的时间复杂度为O(rd))         // 2.所需的辅助空间为n+m         // 3.基数排序是稳定的