基数排序是一种借助多关键字排序思想对单关键字进行排序的方法,它是借助“分配”和“收集”2种操作对单关键字进行排序的。
链式基数排序程序:
c1.h
/**/
/*c1.h(程序名)*/
#include
<
string
.h
>
#include
<
ctype.h
>

#include
<
malloc.h
>
/**/
/*malloc()等*/

#include
<
limits.h
>
/**/
/*INT_MAX等*/

#include
<
stdio.h
>
/**/
/*EOF(=^Z或F6),NULL*/

#include
<
stdlib.h
>
/**/
/*atoi()*/

#include
<
io.h
>
/**/
/*eof()*/

#include
<
math.h
>
/**/
/*floor(),ceil(),abs()*/

#include
<
process.h
>
/**/
/*exit()*/

/**/
/*函数结果状态代码*/
#define
TRUE1
#define
FALSE0
#define
OK1
#define
ERROR0
#define
INFEASIBLE-1

/**/
/*#defineOVERFLOW-2因为在math.h中已定义OVERFLOW的值为3,故去掉此行*/

typedef
int
Status;
/**/
/*Status是函数的类型,其值是函数结果状态代码,如OK等*/

typedef
int
Boolean;
/**/
/*Boolean是布尔类型,其值是TRUE或FALSE*/
c10-3.h
/**/
/*c10-3.h基数排序的数据类型*/
#define
MAX_NUM_OF_KEY8/*关键字项数的最大值*/
#define
RADIX10/*关键字基数,此时是十进制整数的基数*/
#define
MAX_SPACE1000
typedef
struct

...
{

KeysTypekeys[MAX_NUM_OF_KEY];/**//*关键字*/

InfoTypeotheritems;/**//*其它数据项*/
intnext;

}
SLCell;
/**/
/*静态链表的结点类型*/

typedef
struct

...
{

SLCellr[MAX_SPACE];/**//*静态链表的可利用空间,r[0]为头结点*/

intkeynum;/**//*记录的当前关键字个数*/

intrecnum;/**//*静态链表的当前长度*/

}
SLList;
/**/
/*静态链表类型*/


typedef
int
ArrType[RADIX];
/**/
/*指针数组类型*/
源文件:
/**/
/*alg10-11.c链式基数排序*/

typedef
int
InfoType;
/**/
/*定义其它数据项的类型*/

typedef
int
KeyType;
/**/
/*定义RedType类型的关键字为整型*/
typedef
struct

...
{

KeyTypekey;/**//*关键字项*/

InfoTypeotherinfo;/**//*其它数据项*/

}
RedType;
/**/
/*记录类型(同c10-1.h)*/

typedef
char
KeysType;
/**/
/*定义关键字类型为字符型*/
#include
"
c1.h
"
#include
"
c10-3.h
"
void
InitList(SLList
*
L,RedTypeD[],
int
n)

...
{/**//*初始化静态链表L(把数组D中的数据存于L中)*/
charc[MAX_NUM_OF_KEY],c1[MAX_NUM_OF_KEY];

inti,j,max=D[0].key;/**//*max为关键字的最大值*/
for(i=1;i<n;i++)
if(max<D[i].key)
max=D[i].key;
(*L).keynum=(int)(ceil(log10(max)));
(*L).recnum=n;
for(i=1;i<=n;i++)

...{
(*L).r[i].otheritems=D[i-1].otherinfo;

itoa(D[i-1].key,c,10);/**//*将10进制整型转化为字符型,存入c*/

for(j=strlen(c);j<(*L).keynum;j++)/**//*若c的长度<max的位数,在c前补'0'*/

...{
strcpy(c1,"0");
strcat(c1,c);
strcpy(c,c1);
}
for(j=0;j<(*L).keynum;j++)
(*L).r[i].keys[j]=c[(*L).keynum-1-j];
}
}

int
ord(
char
c)

...
{/**//*返回k的映射(个位整数)*/
returnc-'0';
}


void
Distribute(SLCellr[],
int
i,ArrTypef,ArrTypee)
/**/
/*算法10.15*/

...
{/**//*静态键表L的r域中记录已按(keys[0],...,keys[i-1])有序。本算法按*/

/**//*第i个关键字keys[i]建立RADIX个子表,使同一子表中记录的keys[i]相同。*/

/**//*f[0..RADIX-1]和e[0..RADIX-1]分别指向各子表中第一个和最后一个记录*/
intj,p;
for(j=0;j<RADIX;++j)

f[j]=0;/**//*各子表初始化为空表*/
for(p=r[0].next;p;p=r[p].next)

...{

j=ord(r[p].keys[i]);/**//*ord将记录中第i个关键字映射到[0..RADIX-1]*/
if(!f[j])
f[j]=p;
else
r[e[j]].next=p;

e[j]=p;/**//*将p所指的结点插入第j个子表中*/
}
}

int
succ(
int
i)

...
{/**//*求后继函数*/
return++i;
}

void
Collect(SLCellr[],ArrTypef,ArrTypee)

...
{/**//*本算法按keys[i]自小至大地将f[0..RADIX-1]所指各子表依次链接成*/

/**//*一个链表,e[0..RADIX-1]为各子表的尾指针。算法10.16*/
intj,t;

for(j=0;!f[j];j=succ(j));/**//*找第一个非空子表,succ为求后继函数*/
r[0].next=f[j];

t=e[j];/**//*r[0].next指向第一个非空子表中第一个结点*/
while(j<RADIX-1)

...{

for(j=succ(j);j<RADIX-1&&!f[j];j=succ(j));/**//*找下一个非空子表*/
if(f[j])

...{/**//*链接两个非空子表*/
r[t].next=f[j];
t=e[j];
}
}

r[t].next=0;/**//*t指向最后一个非空子表中的最后一个结点*/
}

void
printl(SLListL)

...
{/**//*按链表输出静态链表*/
inti=L.r[0].next,j;
while(i)

...{
for(j=L.keynum-1;j>=0;j--)
printf("%c",L.r[i].keys[j]);
printf("");
i=L.r[i].next;
}
}

void
RadixSort(SLList
*
L)

...
{/**//*L是采用静态链表表示的顺序表。对L作基数排序,使得L成为按关键字*/

/**//*自小到大的有序静态链表,L.r[0]为头结点。算法10.17*/
inti;
ArrTypef,e;
for(i=0;i<(*L).recnum;++i)
(*L).r[i].next=i+1;

(*L).r[(*L).recnum].next=0;/**//*将L改造为静态链表*/
for(i=0;i<(*L).keynum;++i)

...{/**//*按最低位优先依次对各关键字进行分配和收集*/

Distribute((*L).r,i,f,e);/**//*第i趟分配*/

Collect((*L).r,f,e);/**//*第i趟收集*/
printf("第%d趟收集后: ",i+1);
printl(*L);
printf(" ");
}
}

void
print(SLListL)

...
{/**//*按数组序号输出静态链表*/
inti,j;
printf("keynum=%drecnum=%d ",L.keynum,L.recnum);
for(i=1;i<=L.recnum;i++)

...{
printf("keys=");
for(j=L.keynum-1;j>=0;j--)
printf("%c",L.r[i].keys[j]);
printf("otheritems=%dnext=%d ",L.r[i].otheritems,L.r[i].next);
}
}


void
Sort(SLListL,
int
adr[])
/**/
/*改此句(类型)*/

...
{/**//*求得adr[1..L.length],adr[i]为静态链表L的第i个最小记录的序号*/
inti=1,p=L.r[0].next;
while(p)

...{
adr[i++]=p;
p=L.r[p].next;
}
}


void
Rearrange(SLList
*
L,
int
adr[])
/**/
/*改此句(类型)*/

...
{/**//*adr给出静态链表L的有序次序,即L.r[adr[i]]是第i小的记录。*/

/**//*本算法按adr重排L.r,使其有序。算法10.18(L的类型有变)*/
inti,j,k;

for(i=1;i<(*L).recnum;++i)/**//*改此句(类型)*/
if(adr[i]!=i)

...{
j=i;

(*L).r[0]=(*L).r[i];/**//*暂存记录(*L).r[i]*/
while(adr[j]!=i)

...{/**//*调整(*L).r[adr[j]]的记录到位直到adr[j]=i为止*/
k=adr[j];
(*L).r[j]=(*L).r[k];
adr[j]=j;

j=k;/**//*记录按序到位*/
}
(*L).r[j]=(*L).r[0];
adr[j]=j;
}
}

#define
N10
void
main()

...
{

RedTyped[N]=...{...{278,1},...{109,2},...{63,3},...{930,4},...{589,5},...{184,6},...{505,7},...{269,8},...{8,9},...{83,10}};
SLListl;
int*adr;
InitList(&l,d,N);
printf("排序前(next域还没赋值): ");
print(l);
RadixSort(&l);
printf("排序后(静态链表): ");
print(l);
adr=(int*)malloc((l.recnum)*sizeof(int));
Sort(l,adr);
Rearrange(&l,adr);
printf("排序后(重排记录): ");
print(l);
}
程序执行结果如下:
排序前(next域还没赋值):
keynum
=
3
recnum
=
10
keys
=
278
otheritems
=
1
next
=-
858993460
keys
=
109
otheritems
=
2
next
=-
858993460
keys
=
063
otheritems
=
3
next
=-
858993460
keys
=
930
otheritems
=
4
next
=-
858993460
keys
=
589
otheritems
=
5
next
=-
858993460
keys
=
184
otheritems
=
6
next
=-
858993460
keys
=
505
otheritems
=
7
next
=-
858993460
keys
=
269
otheritems
=
8
next
=-
858993460
keys
=
008
otheritems
=
9
next
=-
858993460
keys
=
083
otheritems
=
10
next
=-
858993460
第1趟收集后:
930
063
083
184
505
278
008
109
589
269
第2趟收集后:
505
008
109
930
063
269
278
083
184
589
第3趟收集后:
008
063
083
109
184
269
278
505
589
930
排序后(静态链表):
keynum
=
3
recnum
=
10
keys
=
278
otheritems
=
1
next
=
7
keys
=
109
otheritems
=
2
next
=
6
keys
=
063
otheritems
=
3
next
=
10
keys
=
930
otheritems
=
4
next
=
0
keys
=
589
otheritems
=
5
next
=
4
keys
=
184
otheritems
=
6
next
=
8
keys
=
505
otheritems
=
7
next
=
5
keys
=
269
otheritems
=
8
next
=
1
keys
=
008
otheritems
=
9
next
=
3
keys
=
083
otheritems
=
10
next
=
2
排序后(重排记录):
keynum
=
3
recnum
=
10
keys
=
008
otheritems
=
9
next
=
3
keys
=
063
otheritems
=
3
next
=
10
keys
=
083
otheritems
=
10
next
=
2
keys
=
109
otheritems
=
2
next
=
6
keys
=
184
otheritems
=
6
next
=
8
keys
=
269
otheritems
=
8
next
=
1
keys
=
278
otheritems
=
1
next
=
7
keys
=
505
otheritems
=
7
next
=
5
keys
=
589
otheritems
=
5
next
=
4
keys
=
930
otheritems
=
4
next
=
0
Pressanykeyto
continue
算法的复杂度:O(n)。
程序参考:《《数据结构》算法实现及解析》。