#include<stdio.h>
#include<stdlib.h>
#define MAX_NUM_KEY 8
#define PADIX 10
#define MAX_SPACE 12
typedef 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.基数排序是稳定的
排序算法-----基数排序
最新推荐文章于 2022-04-30 16:53:25 发布