SCAU------8646 基数排序

时间限制:1000MS 代码长度限制:10KB
题型: 编程题 语言: G++;GCC

Description
用函数实现基数排序,并输出每次分配收集后排序的结果

输入格式
第一行:键盘输入待排序关键的个数n
第二行:输入n个待排序关键字,用空格分隔数据

输出格式
每行输出每趟每次分配收集后排序的结果,数据之间用一个空格分隔

输入样例
10
278 109 063 930 589 184 505 069 008 083

输出样例
930 063 083 184 505 278 008 109 589 069
505 008 109 930 063 069 278 083 184 589
008 063 069 083 109 184 278 505 589 930

方法:最低位优先法(LSD)
(具体步骤在代码中)

代码如下:

#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define MAXNUM_KEY 8//构成关键字的组成部分的最大个数
#define RADIX 10
//基数,例如关键字是数字,无疑由0~9组成,基数就是10;
//如果关键字是字符串(字母组成),基数就是 26
#define MAX_SPACE 10000
typedef struct
{//静态链表的结点结构
	int data;//存储的关键字
	int keys[MAXNUM_KEY];//存储关键字的数组(此时是一位一位的存储在数组中)
	int next;//每个结点中存储着下一个结点所在数组中的位置下标
}SLCell;
typedef struct
{//静态链表结构
	SLCell r[MAX_SPACE];//静态链表的可利用空间,其中r[0]为头结点
	int keynum;
	//当前所有的关键字中最大的关键字所包含的位数,例如最大关键字是百,说明所有keynum=3
	int recnum;//静态链表的长度 
}SLList;//静态链表类型
typedef int ArrType[RADIX];//指针数组,用于记录各子序列的首尾位置

void Distribute(SLCell *r,int i,ArrType f,ArrType e)
{//排序的分配算法,i表示按照分配的位次(是个位,十位还是百位),
//f,e分别表示各子序列中第一个记录和最后一个记录的位置
	for(int j=0;j<RADIX;j++) f[j]=0;//初始化指针数组
	for(int p=r[0].next;p;p=r[p].next)
	{
		int j=r[p].keys[i];
		//取出每个关键字的第 i 位,由于采用的是最低位优先法,
		//所以,例如,第 1 位指的就是每个关键字的个位
		if(!f[j]) f[j]=p;
		//如果只想该位数字的指针不存在,说明这是第一个关键字,
		//直接记录该关键字的位置即可
		else r[e[j]].next=p;
		//如果存在,说明之前已经有同该关键字相同位的记录,所以需要将其进行连接,
		//将最后一个相同的关键字的next指针指向该关键字所在的位置,同时最后移动尾指针的位置。
		e[j]=p; //移动尾指针的位置
	}
}

void Collect(SLCell *r,int i,ArrType f,ArrType e)
{
	int j;
	//从 0 开始遍历,查找头指针不为空的情况,为空表明该位没有该类型的关键字
	for(j=0;!f[j];j++);
	r[0].next=f[j];//重新设置头结点
	int t=e[j];//找到尾指针的位置
	while(j<RADIX)
	{
		for(j++;j<RADIX;j++)
		{
			if(f[j])
			{
				r[t].next=f[j];//重新连接下一个位次的首个关键字,队尾连队头
				t=e[j];//t代表下一个位次的尾指针所在的位置
			}
		}
	}
	r[t].next=0;//0表示链表结束
}

//输出静态链表
void print(SLList *L)
{
    for(int p=L->r[0].next; p; p=L->r[p].next) 
	{
        printf("%03d ",L->r[p].data);
    }
    printf("\n");
}

void RadixSort(SLList *L)
{//根据记录中所包含的关键字的最大位数,一位一位的进行分配与收集
	ArrType f,e;
	for(int i=0;i<L->keynum;i++)
	{
		Distribute(L->r,i,f,e);
		Collect(L->r,i,f,e);
		print(L);
	 } 
}

void createlist(SLList *L)
{
	int key,i,j;
	int n;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		cin>>key;
		L->r[i].data=key;
		for(j=0;j<=L->keynum;j++)
		{
			L->r[i].keys[j]=key%10;
			key/=10;
		}
		L->r[i-1].next=i;
	}
	L->recnum=i-1;
	L->r[L->recnum].next=0; 
}

int main()
{
	SLList *L=new SLList;
	L->keynum=3;
	L->recnum=0;
	createlist(L);
	RadixSort(L);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/BitcoinR/article/details/106254302