排序算法-----基数排序
来源:互联网 发布: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.基数排序是稳定的