6-2 基数排序(链式实现)

实现基数排序。

函数接口定义:

void Distribute(SLCell *r,int i,int *f,int *e);

//静态链表L的r域中记录已按(keys[0], …, keys[i-1])有序 //该函数按第i个关键字keys[i]建立RADIX个子表,使同一子表中记录的keys[i]相同。

//f[0..RADIX-1]和e[0..RADIX-1]分别指向各子表中第一个和最后一个记录

void Collect (SLCell *r,int i,int *f,int *e);

//该函数按keys[i]自小至大地将f[0..RADIX-1]所指各子表依次链接成一个链表 //e[0..RADIX-1]为各子表的尾指针

裁判测试程序样例:

#include <iostream>
#define MAXNUM_KEY 8  //关键字项数的最大值 
#define RADIX 10      //关键字基数,此时是十进制整数的基数 
#define MAX_SPACE 10000 
using namespace std;

typedef struct
{ 
  char keys[MAXNUM_KEY];   //关键字 
  int next; 
}SLCell;              //静态链表的结点类型 
typedef struct
{ 
  SLCell r[MAX_SPACE];  //静态链表的可利用空间,r[0]为头结点 
  int keynum;           //记录的当前关键字个数 
  int recnum;          //静态链表的当前长度 
}SLList;              //静态链表类型 

void InitList(SLList *L)
{ 
  int i,n,keynum;     
  cin>>n>>keynum;
  (*L).keynum=keynum;
  (*L).recnum=n;
  for(i=1;i<=n;i++)
    cin>>(*L).r[i].keys;
}

void Distribute(SLCell *r,int i,int *f,int *e); 
void Collect (SLCell *r,int i,int *f,int *e);

void RadixSort(SLList &L)
{ 
   int i;
   int f[RADIX],e[RADIX];
   for(i=0;i<L.recnum;++i)  L.r[i].next=i+1; 
   L.r[L.recnum].next = 0; //将L改造为静态链表
   for(i=L.keynum-1;i>=0;i--) 
   {           
     Distribute(L.r,i,f,e); //第i趟分配
     Collect(L.r,i,f,e);    //第i趟收集
   }
}
 
void print(SLList L)
{  
  int p,flag=1;
  for(p=L.r[0].next;p;p=L.r[p].next)
  {if(flag)
   {cout<<L.r[p].keys;flag=0;}
   else
    cout<<" "<<L.r[p].keys;
   }
}

int main()
{
  SLList l;
  InitList(&l);
  RadixSort(l);
  print(l);
  return 0;
}
/* 请在这里填写答案 */

  AC代码:

void Distribute(SLCell *r, int i, int *f,int *e)
{
	// 静态链表 L 的 r 域中记录已按(keys[0] , ... , keys[i-1])有序。
	// 本算法按第 i 个关键字 keys[i] 建立 RADIX 个子表,使同一子表中记录的 keys[i] 相同。
	// f[0 .. RADIX-1] 和 e[0 .. RADIX-1] 分别指向各子表中第一个和最后一个记录
    for( int j=0; j<RADIX; j++)
	{
		f[j]= 0;
        e[j]= 0;
	}
	for( int p=r[0].next;p;p=r[p].next)
	{
		// 插入第j 个子表中,r[p].keys[i]-'0'也叫映射到数组中
		if(!f[r[p].keys[i]-'0' ])
		{
			f[r[p].keys[i]-'0'] = p;
		}
		else
		{
			r[e[r[p].keys[i]-'0']].next = p;//不为空赋值给表尾的下一个
		}
		e[r[p].keys[i]-'0'] = p;//尾指针设为当前的p
	}
}
void Collect(SLCell *r, int i, int *f,int *e)
{
    //本算法按keys[i]自小到大地将f[0...RADIX-1]所指各子表依次链接成为一个链表
    //e[0..RADIX-1]为各子表的尾指针
    int j;
    for( j=0; !f[j]; j++);                   
    r[0].next=f[j];            
    int k=e[j];                    //k为当前子表的尾指针
    while(j<RADIX)
    {
        for(; j<RADIX; j++)
            if(f[j])        //找下一个非空子表
            {
                r[k].next=f[j];        //连接下一个表的头部
                k=e[j];      
            }
    }
    r[k].next=0;//赋成零形成输出截止条件                    
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值