图论深度优先搜索

栏目: 编程工具 · 发布时间: 5年前

内容简介:推出一个新系列,《看图轻松理解数据结构和算法》,主要使用图片来描述常见的数据结构和算法,轻松阅读并理解掌握。本系列包括各种堆、各种队列、各种列表、各种树、各种图、各种排序等等几十篇的样子。图遍历即图的遍历,指从图中任一顶点出发,对图中的所有顶点访问一次。图的遍历与树的遍历相似,但图的结构更加复杂,比如要考虑回路的情况。图的遍历操作是一种基本操作,很多其他操作都建立在图遍历基础之上。图的遍历算法主要有广度优先搜索和深度优先搜索,这里看深度优先搜索。深度优先搜索(Depth First Search),简称D

推出一个新系列,《看图轻松理解数据结构和算法》,主要使用图片来描述常见的数据结构和算法,轻松阅读并理解掌握。本系列包括各种堆、各种队列、各种列表、各种树、各种图、各种 排序 等等几十篇的样子。

关于图遍历

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

深度优先搜索

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

核心思想

  1. 选择一个初始顶点,并将其标记为已访问;
  2. 若当前顶点存在未被访问过的邻接顶点,则任选一个顶点作为下一个顶点,并将下一个顶点标记为已访问;
  3. 若当前顶点的所有邻接顶点都已被访问过,则回退到最近一次访问的顶点;
  4. 不断执行步骤2和步骤3,直到与起始顶点相通的全部顶点都访问完毕;
  5. 如果图中的顶点还有未被访问的,则再选出其中一个顶点作为起始顶点,继续执行步骤2到步骤4;
  6. 遍历结束。

搜索过程

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

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

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

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

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

图论深度优先搜索

-------------推荐阅读------------

我的开源项目汇总(机器&深度学习、NLP、网络IO、AIML、 mysql 协议、chatbot)

为什么写《Tomcat内核设计剖析》

我的2017文章汇总——机器学习篇

我的2017文章汇总——Java及中间件

我的2017文章汇总——深度学习篇

我的2017文章汇总——JDK源码篇

我的2017文章汇总——自然语言处理篇

我的2017文章汇总——Java并发篇

跟我交流,向我提问:

图论深度优先搜索

欢迎关注:

图论深度优先搜索

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Pro Git (Second Edition)

Pro Git (Second Edition)

Scott Chacon、Ben Straub / Apress / 2014-11-9 / USD 59.99

Scott Chacon is a cofounder and the CIO of GitHub and is also the maintainer of the Git homepage ( git-scm.com ) . Scott has presented at dozens of conferences around the world on Git, GitHub and the ......一起来看看 《Pro Git (Second Edition)》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具