20 基于图的广度优先搜索策略(耿 7.11)

题目

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;
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值