将一个关键字,如278,分为三个关键字‘2’,‘7’,‘8’。
把待排元素按某一位从低到高添加到相应的f-e中,其实f和e只是指向头尾两个元素,链表的连接关系实际上是通过修改r的next指针实现的。
//
// Created by dgm on 19-4-23.
//
#include <iostream>
#define MaxNum 10000
#define Radix 10
using namespace std;
typedef int KeyType;
typedef char* Info;
typedef int ArrType[Radix];
typedef struct {
KeyType key; //单个关键字
Info info;
int next;
}SLCell;
typedef struct {
SLCell r[MaxNum];
int recnum; //待排元素数目
int keynum; //多关键字个数
}SLList; //静态链表
KeyType ord(KeyType k,int i) //取关键字的第i位(将单关键字拆分为多关键字)
{
for (int j = 1; j < i; ++j) k/=10;
return k%10;
}
void Distribute(SLList&L,int i,ArrType&front,ArrType&rear)//按照第i位将每个元素分配到
// 相应的链表中
{
for (int i = 0; i < Radix; ++i) front[i]=0; //初始化
for (auto p = L.r[0].next; p ; p=L.r[p].next) {//p是下标
auto j=ord(L.r[p].key,i); //取得元素的第i位
if (!front[j]) front[j]=p; //如果相应链表为空,加入
else
L.r[rear[j]].next=p; //对照以上图片,实现每一列的链接
//注意f-e并不是链表,而只是首尾元素的下标,真正的链表是在r中通过next实现的
rear[j]=p; //更改链表的尾为新加入元素的下标
}
}
void Collect(SLList&L,ArrType front,ArrType rear)
{
int j;
for (j = 0; !front[j] ; ++j);//第一个非空的列
L.r[0].next=front[j]; //按从左到右的顺序加入到r中
auto t=rear[j]; //当前列的尾,让他通过next指向下一列的头
for (j ; j < Radix; ++j) {
for (j ; !front[j] && j<Radix-1; ++j); //下一个非空列
if (front[j]){
L.r[t].next=front[j];//上一列的尾与这一列的头连起来
t=rear[j];
}
}
L.r[t].next=0; //最后一个元素指向0,标识结束
}
void RadixSort(SLList&L)
{
ArrType front,rear;
for (int i = 0; i < L.recnum; ++i) L.r[i].next=i+1;//建立静态链表
L.r[L.recnum].next=0;
for (int i = 1; i <= L.keynum; ++i) {
Distribute(L,i,front,rear);
Collect(L,front,rear);
}
}
int main()
{
SLList L;
L.recnum=10;
L.keynum=3;
for (int i = 1; i <= L.recnum; ++i) L.r[i].key=rand()%1000;
RadixSort(L);
for (int p = L.r[0].next; p ; p=L.r[p].next) cout<<L.r[p].key<<" ";
cout<<endl;
return 0;
}