算法题 - 判断图是否有环

问题描述:

判断图是否有环

这个题目应该是,2011年某高校的考研题目,正好最近面试碰上,现在翻出来总结一下。

设计算法,采用图的遍历方法(广度优先或者深度优先)判断给定的连通图 G 是否存在回路(环),如何存在回路返回 true,反正返回 false

假设Graph为连通图G的数据类型,其中下列基本操作可以在算法中直接使用:

  • FirstAdjVex(G, v) // 返回连通图 G 中的 v 顶点的第一个邻接点,如果没有返回 NULL
  • NextAdjVex(G, v, w) // 返回连通图 Gv 顶点(相对于 w)的下一个邻接点,如果没有返回 NULL

该算法原型定义为:

  • bool existCyclePath(Graph, int v)

问题分析:

注意事项:

  1. 题目中,已经给出的图 G连通图,所以,可以少考虑一些情况。
  2. 题目中没有提及无向图还是有向图,所以,要特别注意。

解决方法:

  1. 使用图的深度优先搜索,从一个点从发,深度搜索每一条路径。
  2. 对每次走过的路径顶点,进行标记,说明已经走过。
  3. 如果当前顶点,已经被标记走过了,则表示有回路,否则继续深度前行。
  4. 在回溯的过程中,要对当前顶点,重新标记,即,没走过。

代码实现:

const int VEX_MAX = 100;  // 图中最大顶点数
int visited[VEX_MAX];  // 同一条遍历路径上顶点的访问标记

// 从顶点v 出发深度优先搜索图G,判断图中是否存在回路
bool existCyclePath(Graph G, int v){
	// 访问顶点 v
	visited[v] = 1;  // 访问过标记
	// 遍历 v 的邻接点
	for(w=FirstAdjVex(G, v); w!=NULL; w=NextAdjVex(G, v, w)) {
		
		if(visited[w]) return ture;  // 如果w已经访问过,必存在回路,直接返回即可
		
		if(existCyclePath(G, w)) return true;  // 如果从w出发,发现回路,则返回(进入递归调用)
	}
	// 遍历完 v 的所有邻接点,未发现回路,从顶点v返回
	visited[v] = 0;  // 清除访问标记
	return false; // 没发现回路
}

声明: 总结学习,有问题或不妥之处,可以批评指正哦。

题目链接:应该是北工大11年的考研题目。
参考链接:参考历年解析

猜你喜欢

转载自blog.csdn.net/XX_123_1_RJ/article/details/84782980