java 深度优先搜索_图论深度优先搜索

本文主要介绍了图的深度优先搜索算法(DFS),包括其核心思想和搜索过程。通过一个8个顶点的无向加权图实例,详细展示了DFS的遍历步骤,阐述了如何避免重复访问和结束遍历的条件。
摘要由CSDN通过智能技术生成

关于图遍历

图遍历即图的遍历,指从图中任一顶点出发,对图中的所有顶点访问一次。图的遍历与树的遍历相似,但图的结构更加复杂,比如要考虑回路的情况。图的遍历操作是一种基本操作,很多其他操作都建立在图遍历基础之上。图的遍历算法主要有广度优先搜索和深度优先搜索,这里看深度优先搜索。

深度优先搜索

深度优先搜索(Depth First Search),简称DFS。简单来说,深度优先搜索就是对每一个可能的分支深入到不能在深入为止,且每个顶点只能访问一次。DFS的时间复杂度为$O(|V|+|E|)$,其中$|V|$为图的顶点数,$|E|$为图的边数。

核心思想

选择一个初始顶点,并将其标记为已访问;

若当前顶点存在未被访问过的邻接顶点,则任选一个顶点作为下一个顶点,并将下一个顶点标记为已访问;

若当前顶点的所有邻接顶点都已被访问过,则回退到最近一次访问的顶点;

不断执行步骤2和步骤3,直到与起始顶点相通的全部顶点都访问完毕;

如果图中的顶点还有未被访问的,则再选出其中一个顶点作为起始顶点,继续执行步骤2到步骤4;

遍历结束。

搜索过程

在实现深度优先搜索的过程中需要用到一个栈和一个数组,栈用于保存所有待检测的顶点,而数组用于标识哪些顶点已被访问,F表示未被访问,T表示已被访问。

对于一个拥有8个顶点的无向加权图,分别用0-7来表示图的每个顶点,因为遍历与边的权重无关,这里将权重值省略。

ebc47e0e9342c5323d86803968247e84.png

选择3作为初始顶点,将其推入栈中,栈顶的元素即是当前检测的顶点,并将数组对应元素标为T。

3da994cd4b82c8d88dfc5e8975b288e6.png

从顶点3开始,选择一条边进行检测,选择到达顶点1的边,

6df6ffb99261d00a0328efb436ec67ab.png

因为顶点1的访问标记为F,说明还未被访问过,于是将1推入BFS栈中,同时将访问标记改为T。

35a20d66e6b21150f867d614ff4c87a3.png

此时栈顶元素为1,继续从顶点1选择一条边进行检测,选择到达顶点0的边,

513f5b04874c85b8069b85afc2824908.png

因为顶点0的访问标记为F,说明还未被访问过,于是将0推入BFS栈中,同时将访问标记改为T。

30dd0baadb98271dfe9e24ae8bce8fdb.png

此时栈顶的元素为0,继续从顶点0选择一条边进行检测,选择到达顶点1的边,因为访问标记为T,说明已经被访问过,所以访问标记和DFS栈都不更新。

57af1f2b9a478379b4c849d8162964aa.png

继续从顶点0选择一条边进行检测,选择到达顶点2的边,

4658caf29d574a2cf2e2f4a083499497.png

因为顶点2的访问标记为F,说明还未被访问过,于是将2推入BFS栈中,同时将访问标记改为T。

c4212b838739f6754b7b8aeff39c4019.png

此时栈顶的元素为2,继续从顶点2选择一条边进行检测,选择到达顶点0的边,因为访问标记为T,说明已经被访问过,所以访问标记和DFS栈都不更新。

9edad374eb954a017e83b338156ae439.png

继续从顶点2选择一条边进行检测,选择到达顶点1的边,因为访问标记为T,说明已经被访问过,所以访问标记和DFS栈都不更新。

352d3e924f2f9ebc541badd75e8a2a8a.png

此时顶点2的所有边都已经检查完,已经无法继续深入,所以对顶点2进行出栈操作。然后栈顶元素为0,

c791638dc1b481dd37aaa758ed0f7280.png

对于顶点0,顶点2和顶点1的边之前都已经检测过了,已经不存在未访问的边,所以直接对顶点0进行出栈操作。然后栈顶元素为1,

3d68a344f75dca0c78bd84242453cbaf.png

继续从顶点1选择一条未访问的边进行检测,前面检测顶点1时我们是选择了往顶点0的边,所以还剩下顶点2和顶点3未访问过,分别对它们进行检测,发现访问标记都为T,说明已经被访问过,所以访问标记和DFS栈都不更新。

790574bcf8b60679b4924a2508716198.png

a56b089944ee35cc3a19e28faafd5a3e.png

此时顶点1的所有边都已经检查完,对顶点1进行出栈操作。然后栈顶元素为3,

69188db7433db7bf3b46b8e272718268.png

继续从顶点3选择一条未访问的边进行检测,前面检测顶点3时我们是选择了往顶点1的边,所以还剩下顶点4和顶点5未访问过,这次选择顶点4的边。

b9eb861ccf9656a0291366b1eaea70ed.png

因为顶点4的访问标记为F,说明还未被访问过,于是将4推入BFS栈中,同时将访问标记改为T。

17ef5f73533ca6d2cc982d6f5de11b8b.png

此时栈顶元素为4,从顶点4选择一条边进行检测,选择到达顶点3的边,因为访问标记为T,说明已经被访问过,所以访问标记和DFS栈都不更新。

2a83e19857d8d7ae3d06f6f93c2bc32a.png

继续从顶点4选择一条边进行检测,选择到达顶点6的边,

96a7038aa5d3bc322c0c01ce728861bc.png

因为顶点6的访问标记为F,说明还未被访问过,于是将6推入BFS栈中,同时将访问标记改为T。

89625c8b8a57e8aab8b565f7c02a5aa8.png

此时栈顶元素为6,从顶点6选择一条边进行检测,选择到达顶点4的边,因为访问标记为T,说明已经被访问过,所以访问标记和DFS栈都不更新。

c20718040d0114e37ecca40be018d991.png

继续从顶点6选择一条边进行检测,选择到达顶点5的边,

0e45a3f03d9ac8d5572a78165308422f.png

因为顶点5的访问标记为F,说明还未被访问过,于是将5推入BFS栈中,同时将访问标记改为T。

4222521571b535b10bd9087bee44a142.png

此时栈顶元素为5,分别检测顶点5到顶点3和顶点6的边,发现顶点访问标记都为T,无法继续深入,所以对5进行出栈操作,

811b23b70858e989e4533d87d09134f9.png

此时栈顶元素为6,顶点6没有未访问过的边,所以对6进行出栈操作,

0104093debfa4e9ca32ecaf98139dcd6.png

此时栈顶元素为4,顶点4到顶点7的边还未被访问过,对其进行访问,

942ba7957593881e0e70f0921cef7c60.png

因为顶点7的访问标记为F,说明还未被访问过,于是将7推入BFS栈中,同时将访问标记改为T。

84ded82692d4a78eadab6f909433ca81.png

顶点7发现没办法继续深入访问,于是对7进行出栈操作。

9b76a1ae1018cd66cb8fe435911b8355.png

此时栈顶元素为4,顶点4没有未访问过的边,所以对4进行出栈操作,

2228426727222be268a883eb14d51af6.png

此时栈顶元素为3,前面处理顶点3时我们已经检测了顶点1和顶点4的边,所以这次选择顶点5的边。顶点5的访问标记为T,说明已经被访问过,所以访问标记和DFS栈都不更新。

19946bb9c9ffea4ee331751988976d64.png

接着发现顶点3所有边都已经检测完毕,所以对3进行出栈操作。现在DFS栈内没有任何元素,所以我们已经完成了整个遍历过程。

2f2a73ab30e387aa1d646eb60d696254.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值