题目
description:
试基于图的广度优先搜索策略编写程序,判别以邻接表方式存储的有向图中,是否存在由顶点 vi 到顶点 vj(i 不等于 j)。注意:程序中涉及的图的基本操作必须在此存储结构上实现。
input:
第一行输入有向图的顶点数 n 和边数 m,用空格隔开;第二行输入顶点信息;分 m 行输入有向图边的信息,例如顶点对 1,2 表示从顶点 1 到顶点 2 的一条弧。最后一行输入待判别的顶点对 vi,vj.(0<m,n<100)
output:
若有向图中存在由顶点 vi 到顶点 vj 的路径(i 不等于 j),则输出 yes;否则输出 no。
sample_input:
4 4
1 2 3 4
1 2
1 3
1 4
2 3
2 3
sample_output:
yes
思路
图的广度优先遍历类似于树的层次遍历,首先访问起始顶点v,然后选取与v邻接的全部顶点w1,…,wn进行访问,再依次访问与w1,…,wn邻接的全部顶点(已访问过的除外),直到所有顶点被访问过为止。
不同于深度优先遍历使用递归,广度优先需要用到队列。过程如下:
1.任取一结点访问,标记为已访问,入队
int visited[MAX] = {0};
visited[vi] = 1;
Queue[j++] = vi;//vi入队
2.当队列不空时循环执行:出队,依次检查出队顶点的所有邻接顶点,访问未访问过的邻接顶点并将其入队
while (i != j) { //队不空
int v = Queue[i++];//队头元素出队
ArcNode *w = L->vertex[v].firstarc; //指针,设w为v的第一个邻接点
while (w) { //w不为NULL
if (w->adjvex == vj)
return 1;
else {
if (!visited[w->adjvex]) { //未遍历过
visited[w->adjvex] = 1;
Queue[j++] = w->adjvex;
}
w = w->nextarc;//v相对于w的下一个邻接点
}
}
}
3.队列为空时跳出循环
完整代码
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define MAX 10
using namespace std;
/*边表*/
typedef struct ArcNode {
int adjvex; //该弧指向顶点的位置
struct ArcNode *nextarc; //指向下一条弧的指针
} ArcNode;
/*顶点表*/
typedef struct VertexNode {
int data; //顶点数据
ArcNode *firstarc; //指向该顶点第一条弧的指针
} VertexNode;
/*基于邻接表的图*/
typedef struct AdjList {
VertexNode vertex[MAX];
int vexnum, arcnum; //图的顶点数和弧数
} AdjList;
void createAdjList(AdjList *L, int n, int m);
bool BFS(AdjList *L, int vi, int vj);
int main() {
int m, n; //n为顶点数,m为边数
cin >> n >> m;
AdjList *list;
list = (AdjList *)malloc(sizeof(AdjList));
list->vexnum = n;
list->arcnum = m;
createAdjList(list, n, m);
/*查找*/
int vi, vj;
cin >> vi >> vj;
if (BFS(list, vi, vj)) {
printf("yes\n");
} else {
printf("no\n");
}
return 0;
}
void createAdjList(AdjList *L, int n, int m) {
int i, j;
for (i = 0; i < n; i++) { //输入顶点信息,初始化顶点表
cin >> L->vertex[i].data;
L->vertex[i].firstarc = NULL;
}
int a, b; //a记录源点,b记录目标点
for (j = 0; j < m; j++) { //输入边的信息,存储在边表中
cin >> a >> b;
ArcNode *N = (ArcNode *)malloc(sizeof(ArcNode));
N->adjvex = b;
N->nextarc = L->vertex[a].firstarc; //头插法
L->vertex[a].firstarc = N; //为什么不是a-1?
}
}
bool BFS(AdjList *L, int vi, int vj) {
int visited[MAX] = {0};
visited[vi] = 1;
/*初始化空队列*/
int Queue[MAX];
int i, j; //i为头指针,j为尾指针
i = j = 0;
Queue[j++] = vi;//vi入队
while (i != j) { //队不空
int v = Queue[i++];//队头元素出队
ArcNode *w = L->vertex[v].firstarc; //指针,设w为v的第一个邻接点
while (w) { //w不为NULL
if (w->adjvex == vj)
return 1;
else {
if (!visited[w->adjvex]) { //未遍历过
visited[w->adjvex] = 1;
Queue[j++] = w->adjvex;
}
w = w->nextarc;//v相对于w的下一个邻接点
}
}
}
return 0;
}