基数排序【经典】

    基数排序英语Radix sort)是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。

    它是这样实现的:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。


参考 《数据结构》(C语言版)--严蔚敏编著  教材 P288,用C语言实现经典的基数排序算法。用例也参考教材P287.

#include <stdio.h>

#define RADIX 10		//关键字基数,一般为10进制
#define MAX_SPACE 100	//数组最大容量

/*--- 静态链表 ---*/
struct SLCell{
	int keys;	//关键字 用于存储待排序的数
	int next;
}r[MAX_SPACE];

typedef int ArrType[RADIX];

void Distribute(int base,ArrType &f,ArrType &e)	//分配过程
{
	int i,j;
	for(i=0;i<RADIX;++i)f[i]=0;		//各字表初始化为空
	for(i=r[0].next;i;i=r[i].next)
	{
		j=(r[i].keys/base)%10;		//求r[i].keys关键字 的映射
		if(!f[j])f[j]=i;			//如果该字表为空,则头指针指向它
		else r[e[j]].next=i;		//如果不为空,令字表中最后一个数据的next指向它
		e[j]=i;						//更新尾指针
	}	
}

void Collect(ArrType &f,ArrType &e)		//收集过程
{
	int j;
	for(j=0;!f[j];++j);				//找第一个非空字表
	r[0].next = f[j];				//令r[0].next指向第一个非空字表的第一个结点
	int t=e[j];						//t代表目前字表链接起来后的最后一个结点
	while(j<RADIX-1)				//注意!为RADIX-1 ;若为j<RADIX 会溢出错误
	{
		for(++j;j<RADIX-1 && !f[j];++j);		//找下一个非空字表
		if(f[j]){r[t].next=f[j];t=e[j];}		//链接两个非空字表
	}
	r[t].next = 0;			//t指向最后一个非空字表的最后一个结点
}

void RadixSort(int keynum)
{
	ArrType f,e;
	int i,base=1;
	for(i=0;i<keynum;++i)			//按LSD(最低位优先)依次进行分配和收集
	{
		Distribute(base,f,e);
		Collect(f,e);
		base = base * 10;
	}
}

int main()
{
	freopen("in.txt","r",stdin);  
	int n;							//n代表要排序的数据个数
	scanf("%d",&n);
	int i,mmax=0;
	for(i=1;i<=n;i++)
	{
		scanf("%d",&r[i].keys);
		r[i].next=i+1;				//初始化链表为一个接一个向后链接
		if(mmax<r[i].keys)mmax=r[i].keys;
	}
	r[0].next=1;					//第一个数据结点为 1
	r[n].next=0;
	
	printf("Before RadixSort:\n");	//输出排序前数组
	for(i=r[0].next;i;i=r[i].next)
		printf("%d ",r[i].keys);
	printf("\n");

	//printf("mmax: %d\n",mmax);
	int keynum=0;  
    while(mmax>0)					//求得最大值mmax的位数keynum
    {  
        mmax=mmax/10;  
        keynum++;  
    }  
	
	//printf("keynum: %d\n",keynum);
	RadixSort(keynum);

	printf("After RadixSort:\n");		//输出排序后数组
	for(i=r[0].next;i;i=r[i].next)
		printf("%d ",r[i].keys);
	printf("\n");
	return 0;
}


in.txt 输入文件:

10
278 109 63 930 589 184 505 269 8 83



运行结果:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值