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

#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.基数排序是稳定的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值