typedef struct{ int v; int parent; }QUEUE1; int BFSA(AdjGraph *G,int u,int v) { ArcNode *p; SqQueue *qu; InitQueue(qu); int visited[MAXV]; for(int i=0;i<G->n;i++){ visited[i]=0; } QUEUE1 elem; elem.v=u; elem.parent=-1; visited[u]=1; enQueue(qu,v); while(!QueueEmpty(qu)){ deQueue(qu,&v); if(elem.v==v){ while(!QueueEmpty(qu)){ deQueue(qu,&v); } break; p=G->adjlist[elem.v].firstarc; while(p!=NULL){ int w=p->adjvex; if(visited[w]==0){ visited[w]=1; QUEUE1 new_v; new_v.v=w; new_v.parent=elem.v; enQueue(qu,w); } p=p->nextarc; } } if(elem.v!=v){ printf("不存在从%d到%d的路径\n",u,v); return -1; }else{ int len=0; while(elem.parent!=-1){ len++; v=getQueueElem(qu,new_v.parent); } printf("从%d到%d的最短路径长度为:%d\n",u,v,len); return len; } } 修改上述代码,使得满足用BFS求从u到v的最短路径,需要修改队列的元素类型,每个元素记录下它的前驱结点(parent指针指示),而不是用dist记录长度的方式实现
时间: 2023-10-20 19:05:21 浏览: 161
修改后的代码如下:
```
typedef struct{
int v;
int parent;
}QUEUE1;
int BFS(AdjGraph *G, int u, int v) {
ArcNode *p;
SqQueue *qu;
InitQueue(qu);
int visited[MAXV];
for(int i = 0; i < G->n; i++) {
visited[i] = 0;
}
QUEUE1 elem;
elem.v = u;
elem.parent = -1;
visited[u] = 1;
enQueue(qu, elem);
while(!QueueEmpty(qu)) {
deQueue(qu, &elem);
if(elem.v == v) {
while(!QueueEmpty(qu)) {
deQueue(qu, &elem);
}
break;
}
p = G->adjlist[elem.v].firstarc;
while(p != NULL) {
int w = p->adjvex;
if(visited[w] == 0) {
visited[w] = 1;
QUEUE1 new_v;
new_v.v = w;
new_v.parent = elem.v;
enQueue(qu, new_v);
}
p = p->nextarc;
}
}
if(elem.v != v) {
printf("不存在从%d到%d的路径\n", u, v);
return -1;
} else {
int len = 0;
while(elem.parent != -1) {
len++;
elem = getQueueElem(qu, elem.parent);
}
printf("从%d到%d的最短路径长度为:%d\n", u, v, len);
return len;
}
}
```
主要的修改在于将队列的元素类型从普通的整型变成了 `QUEUE1` 结构体,该结构体中除了记录节点编号 `v` 外,还记录了该节点的父节点编号 `parent`。在每次入队时,将新的元素的 `parent` 字段设置为当前节点的编号 `elem.v`,表示新节点的前驱是当前节点。在出队时,根据当前节点的 `parent` 字段找到其对应的前驱节点,直至找到起始节点为止,计算路径长度即可。
需要注意的是,在计算路径长度时,每次修改了 `elem` 的值,因此需要新建一个变量来保存当前的节点,避免对 `elem` 值的修改对后续计算造成影响。
阅读全文