关于链式基数排序问题!!!
下面的程序段不理解,请高手指教!谢谢!
#include "stdfx.h "
#include "stdio.h "
#define N 11
#define d 3
#define rd 10
struct element
{
int key[d];
int next;
};
typedef element sqlist[N];
sqlist R={{{0,0,0},0},{{2,7,8},0},{{1,0,9},0},{{0,6,3},0},{{9,3,0},0},{{5,8,9},0},{{1,8,4},0},
{{5,0,5},0},{{2,6,9},0},{{0,0,8},0},{{0,8,3},0}};
//定义数据
void radixsort(sqlist r,int n)
{
int f[10],int e[10];
int i,j,k,p,t;
int m;
for(j=1;j <N;j++)
{
for(i=0;i <d;i++)
printf( "%3d ",r[j].key[i]);///display the data;
printf( "\n ");
}
printf( "\n ");
for(k=1;k <=n-2;k++)////建立静态链表为什么这个地方建立静态链表干什么用,不是已经建立链表sqlist R了吗????????
r[k].next=k+1;//这个地方干什么用呢???????????
r[n-1].next=0; ///最后收尾,收尾是什么意思呢??????????
p=1; //第一个数据开始
for(i=d-1;i> =0;i--)
{
for(j=0;j <rd;j++)
{
f[j]=0; ///队列头初始为0
}
while(p!=0)
{
k=r[p].key[i]; //第p个数据的第i位 123 则先取3低未,数组是高位
if(f[k]==0) f[k]=p;//队列头为零,p给队列头
else
{
r[e[k]].next=p;
//有数据了,已经放入队列了,连接上下数据,p:下数据 ,举例说明r[e[k]].next=p;是怎样连接上下数据的?????不明白指针怎样连接上下节点的????
}
e[k]=p; //队尾=下数据(当前)不明白??????????
p=r[p].next;//静态指针后移,取下一个数据
}
j=0;
while(f[j]==0)
j++; //寻找非空队列
m=p=f[j] ; t=e[j]; //这里进行赋值运算干什么用呢????????????????????
while(j <rd-1)
{
j++;
if(f[j]!=0)
{
r[t].next=f[j]; //头尾相连,能否解释一下怎么进行头尾相连的????????????????
t=e[j];////尾给了下一个头????????????
}
}
r[t].next=0; //最后一个数据为0,最后一个数据为什么为0呢???????????????????
}
while(m> 0)
{
for(i=0;i <d;i++)
{
printf( "%3d ", r[m].key[i]);
}
printf( "\n ");
m=r[m].next; ///输出排序后的静态链表
}
}
[解决办法]
我虽然没有完全看懂这个程序,但其中的许多地方还是明白的,希望给你带来帮助。
1。先说说数据结构的定义:
key 表示一个3位数,key[0]:百位,key[1]:十位,key[2]:个位
next:下一个节点的序号,和通常的表示法有所不同,next:用整数来表示,而不是用指针来表示,0:表示没有后继,即这个节点是链表的最后一个节点。因为0 有特殊的含义,故数组R[0]不使用。下面2句话该明白了。
r[n-1].next=0; ///最后收尾,收尾是什么意思呢??????????
r[t].next=0; //最后一个数据为0,最后一个数据为什么为0
2。“ for(k=1;k <=n-2;k++)////建立静态链表为什么这个地方建立静态链表干什么用,不是已经建立链表sqlist R了吗????????
r[k].next=k+1;//这个地方干什么用呢???????????”
数组R初始化时,仅对key赋值,next 并未包含有意义的值,换句话,这个项链各个珠子并没有穿起来。这部分代码将 第2个元素作为第一个元素的后继,第三个元素作为第二个元素的后继, 及 1-> 2-> 3 -> 4-> 5-> 6-> 7-> 8-> 9-> 10-> 0
3: “ //有数据了,已经放入队列了,连接上下数据,p:下数据 ,举例说明r[e[k]].next=p;是怎样连接上下数据的?????不明白指针怎样连接上下节点的????
}
e[k]=p; //队尾=下数据(当前)不明白??????????
”
说明:临时数组,f和e, 分别表示 子链表 头,和子链表 尾。
这个排序程序总共需要3轮,在排序过程中,仅修改next的值,实际数据并不交换,即排序前前 R[i].key 是什么,排序后仍然是什么。
这个数组R[1] 到 R[10] 的 key 为: 278,109,063,930,589,184,505,269,008,083
第一轮,仅对个位数排序,排序完成后,是这个样子的( 数字表示元素序号)
以序号表示: 4-> 3-> 10-> 6-> 7-> 1-> 9-> 2-> 5-> 8-> 0 ,
以key表示:(930)-> (063)-> (083) -> (184) -> (505)-> (278)-> (008)-> (109)-> (589)-> (269)
f[k]: 表示关键字 k 的子链表第一节点的序号。
e[k]:表示关键字 k 的子链表最后一个节点的序号。
在第一轮排序过程中,仅对个位数字排序,关键字为个位数字,我们注意到:109,589,269 这三个元素的关键字都是9,109-> 589-> 269 构成一个子链表 因此,r[9]=2,指向子链表第1个元素(109),其需序号是2,e[9]=8,指向子链表的最后一个元素269,其序号是8。如果某个关键字只有一个元素,则e[k]=r[k],如果某个关键字,如第一轮排序过程中,任何一个数字的个位数 都不是1,2。 因此f[1]=f[2]=0; e[1]=e[2]= 未初始华值。
后面的部分就不太明了,只知道第一轮排序后,链表是按个数数字由小到大的顺序排列的,
第2轮排序完成后,链表是按后2位(十位和各位)数数字由小到大的顺序排列的,第3轮排序完成后,链表则完全按这些3位数字的大小排序了。其第一个节点(值最小的节点,值为“008”)的
序号是9,下面这段代码依次 打印下一个节点,打印出来的数据 就是一个有序的了。
while(m> 0)
{
for(i=0;i <d;i++)
{
printf( "%3d ", r[m].key[i]);
}
printf( "\n ");
m=r[m].next; ///输出排序后的静态链表
}