没做这个算法之前觉得静态链表没什么用,写了这个算法才发现原来静态链表是如此的巧妙,才发现之前的看法是多么的浅薄无知,看来以后还要更虚心了,嘿嘿...
基数排序,关键是两个过程,分配和回收,分配是按关键字顺序将记录进行分类为,回收是将分配过程中顺序打乱的记录重新链接成静态链表。这样从按一定顺序对关键字进行分配和回收到最后就能得到一个有序序列。即为基数排序原理。
"RadixSort.h"
#define MAX_NUM_OF_KEY 8
#define Radix 10
#define MAX_SPACE 10000
typedef int KeyType;
typedef struct SLCell
{
KeyType keys[MAX_NUM_OF_KEY];
int next;
SLCell()
{
for(int i=0;i<MAX_NUM_OF_KEY;i++)
keys[i]=0;
next=0;
}
}SLCell;
typedef struct SLList
{
SLCell r[MAX_SPACE];
int keynum;
int recnum;
SLList()
{
keynum=0;
recnum=0;
}
}SLList;
typedef int ArrType[Radix];
void PrintSSList(const SLList &L)//输出静态链表
{
for(int i=L.r[0].next;i!=0;i=L.r[i].next)
{
int j=L.keynum-1;
while(L.r[i].keys[j]==0&&j>0) j--;
if(j==0)
cout<<0;
else
{
while(j>=0)
cout<<L.r[i].keys[j--];
}
cout<<" ";
}
cout<<endl;
}
void GetRandomNum(SLList&L,int nnum,int base)
//得到nnum个在1...base之间的随机数
{
srand((unsigned)time(NULL));
int num=base,t;
while(num!=0)//得到关键字个数
{
L.keynum++;
num/=Radix;
}
for(int i=1;i<=nnum;i++)
{
num=rand()%base+1;
t=0;
while(num!=0)//分配关键字
{
L.r[i].keys[t++]=num%Radix;
num/=Radix;
}
L.recnum++;//静态链表长度增一
}
for(int i=0;i<L.recnum;i++)//链接静态链表
L.r[i].next=i+1;
}
void Distribute(SLCell *r,int i,ArrType&f,ArrType&e)
//按第i个关键字分配记录
{
for(int i=0;i<Radix;i++)
f[i]=0;
int p,j;
for(p=r[0].next;p!=0;p=r[p].next)
{
j=r[p].keys[i];
if(f[j]==0)
f[j]=p;
else
r[e[j]].next=p;
e[j]=p;
}
}
void Collect(SLCell *r,ArrType&f,ArrType&e)
//回收记录
{
int j;
for(j=0;f[j]==0;j++);
r[0].next=f[j];
int t=e[j];
while(j<Radix)
{
for(j++;j<Radix&&f[j]==0;j++);
if(j<Radix&&f[j]!=0)
{
r[t].next=f[j];
t=e[j];
}
}
r[t].next=0;
}
void RadixSort(SLList&L)//基数排序
{
ArrType f,e;
for(int i=0;i<L.keynum;i++)
{
Distribute(L.r,i,f,e);
Collect(L.r,f,e);
}
}
"main.cpp"
#include<ctime>
#include<iostream>
using namespace std;
#include"RadixSort.h"
int main()
{
SLList L;//定义静态链表
GetRandomNum(L,10,100);//得到随机数
PrintSSList(L);//输出
RadixSort(L);//基数排序
PrintSSList(L);//输出
system("pause");
}