我没看懂这个题目,谁看懂了?

时间:2022-02-04 04:22:15
设计一个函数利用遍历图的方法输出一个无向图G中从顶点Vi到Vj的长度为L的简单路径,假设无向图采用邻接表存储结构。
解:本题的算法思想是:利用深度优先搜索遍历,设栈(stack)保存遍历路径上的顶点,并以d记下当前的路径长度。从V=Vi出发,找V的邻接顶点W,若W已访问过,则找下一个邻接顶点;W=Vj,且d=L-1,则路径即为所求;若W<>j,且d<L-1,则从W出发继续遍历,否则找下一个邻接顶点,若找不到下一个邻接顶点(设W=0),则退栈,找前一顶点的下一个邻接顶点,若栈空,则说明没有这样的路径。
   因此,实现本题功能的函数如下:
#define MAXVEX 100
void path(adj,i,j,L)
int I,j,L

{
 int v,w,top=0,d=0,head;
 int stack[MAXVEX],visited[MAXVEX];
struct vexnode *p;
v=Vi;
visited[Vi]=1; head=1;
do 
{
if (head) p=adj[v]->link;
else { 
head=0;
p=p->next;
}
if (p= =Null) w=0;
else w=p->adjvex;
if (w!=0) 
   if (visited[w]= =0)
if (w= = Vi && d==L-1)
{
d++;
top++;
stack[top]=v;
}
if (w!=Vj&&d<L-1)
{
d++;
top++;
stackp[top]=v;
visited[w]=1;
v=w;
head=1;

}
else if (top>0)
{
visited[v]=0;
v=stack[top];
head=1;
top--;
d--;
}
}while ((top!=0)| | w==0)&&(d!=1))

if (top>0)  
  for(I=1;I<top;I++) 
printf(“%d”,stack[i]);
else printf(‘没有这样的路径!’);
}

11 个解决方案

#1


程序有错误,没有head=0的赋值。虽然条件语句里有,但head永远不会=0。除此之外之外,思路很清晰。不知你哪里有疑问?

#2


确实head没有赋0,我也看了半天。但书上确实是这么写的,我想不出在哪里赋head为0。

从V=Vi出发,找V的邻接顶点W,若W已访问过,则找下一个邻接顶点; 
这里找下一个顶点是怎么实现的。谢谢!

#3


head=0的赋值大概在
else if (top>0)
{
visited[v]=0;
v=stack[top];
head=0;  /*不是=1 */
top--;
d--;
}
此时p=null,所以出栈,置head=0,表明取邻接表的下一个顶点。
此程序是深度优先遍历。先从vi开始遍历每个连表的表头的adj[v]->link顶点,如果为空,出栈取前一个顶点的下一个邻接顶点p->next.如果你把邻接表的结构搞清楚了就明白了.邻接表的结构是这样的.
adj[0]->link(指向v1)--v1->next(指向v2)--v2->next--null  
adj[1]->link--v3->next--v4->next--null
adj[2]->link=null
....
adj[4]-link=null.
如果还又疑问,请指明.

#4


if (w!=Vj&&d<L-1)
{
d++;
top++;
stackp[top]=v;
visited[w]=1;
v=w;
head=1;

}
这个地方不管W是不是访问过或为0都进栈?

#5


else if (top>0)
{
visited[v]=0;
v=stack[top];
head=1;
top--;
d--;
}而且这里退栈的时候,返回去p=p->next应该不会是下一个邻接顶点。

#6


w不管是不是访问都近栈,w=0因该不近栈,如果近栈,当w出栈时哪里有p->next。程序可能有错误。我觉得应该这样:
if (w!=0) 
  {                          /*加大括号*/ 
   if (visited[w]= =0)
if (w= = Vi && d==L-1)
{
d++;
top++;
stack[top]=v;
}
if (w!=Vj&&d<L-1)
{
d++;
top++;
stackp[top]=v;
visited[w]=1;
v=w;
head=1;

}
 }                              /*  对应前面的大括号*/
else if (top>0)
{
visited[v]=0;
v=stack[top];
head=1;
top--;
d--;
}
}while ((top!=0)| | w==0)&&(d!=1))

#7


退栈的时候是不是应该加上p=adj[v]->link;

#8


能否告知这是那里的题目?

#9


清华的一本数据结构习题。

#10


修正一下,加上大括号后,w应该没有访问过进栈,如果访问了也进栈,就形成回路了。另外w=0应该也进栈,否则不用退栈,只取栈顶元素。当访问到邻接表连尾的时候,必须有退栈过程。大括号加错了
退栈的时候不应该加上p=adj[v]->link,因为退栈后转到前面
if (head) p=adj[v]->link;
else { 

p=p->next;
}
这里给p赋值。
此题的毛病在于对什么时候退栈的判断错误。
此题如用递归,可简单些,再和回溯配合,可以找出所有长度为L的路径。

#11


OK,谢谢!

#1


程序有错误,没有head=0的赋值。虽然条件语句里有,但head永远不会=0。除此之外之外,思路很清晰。不知你哪里有疑问?

#2


确实head没有赋0,我也看了半天。但书上确实是这么写的,我想不出在哪里赋head为0。

从V=Vi出发,找V的邻接顶点W,若W已访问过,则找下一个邻接顶点; 
这里找下一个顶点是怎么实现的。谢谢!

#3


head=0的赋值大概在
else if (top>0)
{
visited[v]=0;
v=stack[top];
head=0;  /*不是=1 */
top--;
d--;
}
此时p=null,所以出栈,置head=0,表明取邻接表的下一个顶点。
此程序是深度优先遍历。先从vi开始遍历每个连表的表头的adj[v]->link顶点,如果为空,出栈取前一个顶点的下一个邻接顶点p->next.如果你把邻接表的结构搞清楚了就明白了.邻接表的结构是这样的.
adj[0]->link(指向v1)--v1->next(指向v2)--v2->next--null  
adj[1]->link--v3->next--v4->next--null
adj[2]->link=null
....
adj[4]-link=null.
如果还又疑问,请指明.

#4


if (w!=Vj&&d<L-1)
{
d++;
top++;
stackp[top]=v;
visited[w]=1;
v=w;
head=1;

}
这个地方不管W是不是访问过或为0都进栈?

#5


else if (top>0)
{
visited[v]=0;
v=stack[top];
head=1;
top--;
d--;
}而且这里退栈的时候,返回去p=p->next应该不会是下一个邻接顶点。

#6


w不管是不是访问都近栈,w=0因该不近栈,如果近栈,当w出栈时哪里有p->next。程序可能有错误。我觉得应该这样:
if (w!=0) 
  {                          /*加大括号*/ 
   if (visited[w]= =0)
if (w= = Vi && d==L-1)
{
d++;
top++;
stack[top]=v;
}
if (w!=Vj&&d<L-1)
{
d++;
top++;
stackp[top]=v;
visited[w]=1;
v=w;
head=1;

}
 }                              /*  对应前面的大括号*/
else if (top>0)
{
visited[v]=0;
v=stack[top];
head=1;
top--;
d--;
}
}while ((top!=0)| | w==0)&&(d!=1))

#7


退栈的时候是不是应该加上p=adj[v]->link;

#8


能否告知这是那里的题目?

#9


清华的一本数据结构习题。

#10


修正一下,加上大括号后,w应该没有访问过进栈,如果访问了也进栈,就形成回路了。另外w=0应该也进栈,否则不用退栈,只取栈顶元素。当访问到邻接表连尾的时候,必须有退栈过程。大括号加错了
退栈的时候不应该加上p=adj[v]->link,因为退栈后转到前面
if (head) p=adj[v]->link;
else { 

p=p->next;
}
这里给p赋值。
此题的毛病在于对什么时候退栈的判断错误。
此题如用递归,可简单些,再和回溯配合,可以找出所有长度为L的路径。

#11


OK,谢谢!