数据结构 排序 基数排序

基数排序是一种借助多关键字排序思想对单关键字进行排序的方法,它是借助“分配”和“收集”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)。

程序参考:《《数据结构》算法实现及解析》。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值