判断图有无环_判断无向图/有向图中是否存在环

本文主要针对如何判断有向图/无向图中是否存在环的问题进行简单的论述。

一 无向图

1.利用DFS进行判断

利用DFS判断有向图是否存在环,是最为常用的一种方法,虽然这种方法很常用,但可参考的代码的实现比较少,下面对这种方法及其实现进行详细的阐述。

首先,利用DFS判断无向图中是否换的原理是:若在深度优先搜索的过程中遇到回边(即指向已经访问过的顶点的边),则必定存在环。

所以说,是否存在环的关键在于是否存在满足条件的“回边”,那么如何判断回边呢?

(1)首先,对图中的所有顶点定义三种状态:顶点未被访问过、顶点刚开始被访问、顶点被访问过并且其所有邻接点也被访问过。这三种状态,在visited数组中分别用0、1、2来表示。那么,存在环的情况可以定义为:在遍历过程中,发现某个顶点的一条边指向状态1的顶点,此时就存在环。

(2)此外,我们要定义一个father数组,用以存储在DFS过程中顶点的父顶点(或者说是生成树上的父节点)。其主要作用是为了区分邻接点中环中的顶点和遍历过程中的父节点 (单纯的用visited数组无法区分)。

整个过程的实现代码如下:

#define MAX_NUM 100

#define INF 0x7fffffff

/*DFS判断无向图中是否有环*/

class Graph

{

public:

int vertexNum;//顶点个数

int arcNum;//弧的个数

int vertex[MAX_NUM];//顶点表

int arc[MAX_NUM][MAX_NUM];//弧信息表

};

int visited[MAX_NUM];//顶点访问表

int father[MAX_NUM];//父节点表问表

void DFS(int v,Graph G)

{

visited[v] = 1;

for(int i = 0 ; i < G.vertexNum; i++)

{

if(i != v && G.arc[v][i] != INF)//邻接矩阵中节点v的邻接点

{

if(visited[i] == 1 && father[i] != v)//不是父节点,而且还访问过,说明存在环

{

cout<

int temp = v;

while(temp != i)

{

cout<";//输出环

temp = father[temp];

}

cout<

}

else

if(visited[i] == 0)

{

father[i] = v;//更新father数组

DFS(i,G);

}

}

}

visited[v] = 2;//遍历完所有的邻接点才变为状态2

}

void DFSTraverse(Graph G)

{

memset(visited,0,sizeof(visited));

memset(father,-1,sizeof(father));

for(int i = 0 ; i < G.vertexNum; i++)

if(!visited[i])

DFS(i,G);

}

由此可见,visited数组相对于一般的情况,增加了个状态2,主要是为了防止在回溯过程中进行误判。所以才能仅用father数组和状态1判断存在环。

由于使用的是邻接矩阵来存储,所以该算法的时间复杂度为O(n^2),空间复杂度为O(n)。

2.其他方法本文不再详述。

二 有向图

1.拓扑排序

关于拓扑排序,资料很多,本文不再详述。

原文:https://www.cnblogs.com/wangkundentisy/p/9320499.html

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值