6-6图-深度优先搜索DFS

深度优先搜索

一.基础知识
Depth-First-Search
DFS深度优先搜索
往深处走

先看树
访问顺序12563478
在这里插入图片描述
过程:首先访问1,并置1标记已访问;然后访问与a邻接且未被访问的顶点2(FirstNeighbor),标记2为已访问;然后访问与2邻接且未被访问的顶点5,标记5为已访问。此时5没有未被访问过的邻接点,返回上一个访问过的顶点2,访问与其邻接且未被访问的顶点6(NextNeighbor),标记6为已访问…

故深度优先搜索类似于树的先序遍历

二.进阶

再看图
在这里插入图片描述
如果先从2开始访问,第一个相连的是1,再看1的第一个邻接点(希望是5)是2,所以需要一个visited数组来记录已经访问过的结点并跳过本次循环,然后通过1的NextNeighbor找到5;同理,后面通过2的NextNeighbor找到6,通过6的NextNeighbor找到3,与3邻接的4号顶点,4号NextNeighbor到7,最后到8,再层层返回。过程中通过函数调用实现。

注:可以通过深度优先遍历来判断有向图是否有环(回路):在遍历过程中如果遇到要访问的结点已在栈中就是有环

练习:从3出发DFS
解:3476215退到7,8
即34762158

另外,也可以通过观察邻接表来推算DFS

练习:从1出发DFS
解:12往深走,(21)6,(62)3,(3)4,(43)7,(7346)8,(847),回退,(73468),回退(4378),回退,(3467),回退,(6237),回退,(216),回退,(12)5
即12634785
在这里插入图片描述
(矩阵可自己练习)

回顾总结:
(1)同一个图的邻接矩阵表示方式唯一,因此深度优先遍历序列唯一
(2)同一个图的邻接表表示方式不唯一,因此深度优先遍历序列不唯一

DFS初步构建代码

bool visited[MAX_VERTEX_NUM];//访问标记数组
void DFSTraverse(Graph G) {
	for (v = 0; v < G.vexnum; ++v)
		visit[v] = FALSE;//初始化数组,用FALSE表示未访问的结点
	DFS(G,v);
}
void DFS(Graph G, int v) { //从顶点v出发
	visit(v);
	visited[v] = TRUE;//用TRUE表示已访问
	for(w = FirstNeighbor(G, v); w >= 0;w=NextNeighbor(G,v,w))
		if (!visited[w])//w为v的尚未访问的邻接顶点
		{
			DFS(G, w);
		}
}

完成了题目要求,但对于非连通图等特殊情况没有考虑到,无法遍历所有顶点
在这里插入图片描述

代码优化

bool visited[MAX_VERTEX_NUM];//访问标记数组
void DFSTraverse(Graph G) {
	for (v = 0; v < G.vexnum; ++v)
		visit[v] = FALSE;//初始化数组,用FALSE表示未访问的结点
	for(v=0;v<G.vexnum;++v)//添加代码
		if (!visited[v])
		{
			DFS(G, v);//从v=0开始遍历
		}
}
void DFS(Graph G, int v) { //从顶点v出发
	visit(v);
	visited[v] = TRUE;//用TRUE表示已访问
	for(w = FirstNeighbor(G, v); w >= 0;w=NextNeighbor(G,v,w))
		if (!visited[w])//w为v的尚未访问的邻接顶点
		{
			DFS(G, w);
		}
}

故:

【无向图】

(1)此代码中DFSTraverse函数中调用DFS的次数正好等于连通分量数
(2)对于连通图,只需调用一次DFS

【有向图】

调用DFS函数的次数需要具体分析
(1)若起始顶点到其他各顶点都有路径,则只需要调用一次DFS函数(例如从7开始1次,从2开始多次)
在这里插入图片描述
(2)对于强连通图,从任一结点出发都只需调用1次DFS
在这里插入图片描述

三.性能分析

1.空间复杂度:DFS算法是一个递归算法,主要来源于DFS的递归调用,需要借助一个递归工作栈实现

(1)最坏情况(默认):O(|V|)
在这里插入图片描述
(2)最好情况:O(1)
在这里插入图片描述
2.时间复杂度

时间复杂度=访问各结点所需时间+探索各条边所需时间

邻接矩阵:O(|V²|)
邻接表:O(|V|+|E|)
在这里插入图片描述
四.深度优先生成树和生成森林、图树转化

图树转化
(1)从2开始,按照刚刚的访问次序,通过红色的边可以直接转化成树
在这里插入图片描述

转化为
在这里插入图片描述

(2)即使从同一个顶点开始,也可能得到不一样的深度优先遍历序列,即对应不同的深度优先生成树
在这里插入图片描述
转化为
在这里插入图片描述
同样
(1)同一个图的邻接矩阵表示方式唯一,因此深度优先生成树唯一
(2)同一个图的邻接表表示方式不唯一,因此深度优先生成树不唯一

注:对连通图调用DFS才能产生深度优先生成树,否则产生的将是深度优先生成森林

在这里插入图片描述

转变为
在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡__卡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值