【数据结构】6.5 图的遍历

news2024/11/16 18:44:27

文章目录

  • 遍历定义
  • 深度优先搜索(DFS)
    • 算法步骤
    • 邻接矩阵上的遍历
    • 邻接矩阵深度优先算法
    • DFS算法效率分析
  • 广度优先搜索(BFS)
    • 邻接表的广度优先算法
    • BFS算法效率分析
    • DFS与BFS算法效率比较

遍历定义

  • 和树的遍历类似,图的遍历也是从图中的某一个顶点出发,按照某种方法对图中所有顶点访问且仅访问一次,就叫做图的遍历,它是图的基本运算
  • 图的遍历算法是求解图的连通性问题、拓扑排序和关键路径等算法的基础。

举个栗子

从景区的大门口出发,如何走才能访问且仅访问一次每一个结点,这样一个问题就可以抽象成一个

  • 用顶点来表示每个要参观的景点。
  • 用顶点之间的边来表示连个景点之间的路线。
  • 将所有景点都走一遍,就是对图中所有顶点遍历的一个过程。

遍历实质找每个顶点的邻接点的过程

在这里插入图片描述

图的特点

  • 图中可能存在回路,且图的任一顶点都有可能与其他顶点相通,在访问完某个顶点之后可能沿着某些边又回到了层间访问过的顶点
    • 比如上面的图:从V1出发,依次经过了V2 V4 V8 V5 最后又回到了 V2,此时这个V2已经访问过一次,就不再访问了。
    • 将访问过的顶点记录下来

如何避免重复访问

解决思路:设置辅助数组 visited[n],用来标记每个被访问过的顶点。

  • 初始状态 visited[i] = 0
  • 顶点 i 被访问,则 visited[i] = 1,防止被多次访问。

深度优先搜索(DFS)

算法思想

仿树的先序遍历,一条道走到黑

举个栗子

  1. 先点亮第一盏灯,此时发现和这盏灯连接的灯还有三盏灯,选择与之连接的一盏灯去点亮它。

在这里插入图片描述>在这里插入图片描述

  1. 接下来从这盏灯出发不回去,继续按照深度遍历的方法往下访问。

在这里插入图片描述

  1. 到了有多个邻接点的顶点时,这时候发现有三盏灯可以被点亮,选择一个顶点执行深度遍历访问下去,一条道走到黑,直到不能再继续往深层走

在这里插入图片描述

  1. 发现无路可走的时候,此时就回退到上一个位置看看还有没有没有被点亮的灯,如果访问过了,则继续往回退,直到发现还有没被访问过的顶点为止。.

在这里插入图片描述

  1. 当退到某个顶点所邻接的顶点还有没被访问过的顶点时,继续往里走。

在这里插入图片描述在这里插入图片描述

  1. 当发现顶点访问过时,则继续往回退,直到退回到起始点时,则表示遍历完毕

在这里插入图片描述

算法步骤

  1. 在访问图中某一个起始点 V,从 V出发,访问它的任一邻接顶点 W1当有多个没有访问的邻接点可以访问时,任选其一
  2. 再从 W1 出发,访问与 W1 邻接但还未被访问过的顶点 W2.
  3. 然后从 W2 出发,进行类似的访问…
  4. 如此进行下去,直到到达所有的邻接顶点都访问过的顶点 u 为止。
  5. 接着,回退一步,遇到前依次刚被访问过的顶点,看是否还有其他没有被访问的邻接顶点。
    • 如果有:则访问此顶点,之后再从此顶点出发,进行与前面类似方法的访问。
    • 如果没有:就再退回一步进行搜索。重复上述过程直到连通图汇总所有顶点都被访问过为止

在这里插入图片描述

邻接矩阵上的遍历

  • 深度优先搜索遍历连通图是一个递归的过程。
  • 二维数组的第 i 行 i 列用来判断某个顶点到其他顶点之间是否有边。
    • 如:第一行/列 就是判读顶点 1 到其余顶点间是否有边,V1 到 V2 V3 V4 有边记为1,其余记为 0。
  • 光用邻接矩阵的话就没有办法判断某个顶点是否有被访问过,所以此时辅助数组 visited[i] 就派上用场了。

在这里插入图片描述

  1. 开始先将辅助数组内的值全部置为0,表示全都顶点都没访问过,访问过的顶点则将该顶点在辅助数组中的位置的值置为1。

在这里插入图片描述

  1. 假设起点是从顶点 2 开始,那么 2 肯定被访问过了,将 visited[2] 值置为 1。

在这里插入图片描述

  1. 然后去看 2 的邻接点有哪些没被访问过,然后去访问在数组对应位置上为 0 的顶点 2 邻接点。
    • 找邻接点:2 号顶点的邻接点都在邻接矩阵中表示出来了,在行下标为 2 的一维数组中,去找值为 1 的顶点。

在这里插入图片描述

  1. 顶点 1 在辅助数组中的值为 0,访问它,然后将 visited[1] 的值改为1.

在这里插入图片描述

  1. 然后再从顶点 1 往下遍历,从邻接矩阵中一个一个找邻接点,然后从辅助数组中判断找出来的邻接点是否被访问过。
    • 顶点1 的第一个邻接点 2 被访问过了,继续找下一个邻接点 3,发现还没被访问过,走 忽略。
    • 然后将 visited[3] 置为1.

在这里插入图片描述
在这里插入图片描述

  1. 到了顶点 3 之后就从 3 出发继续执行深度遍历
    • 从邻接矩阵中找顶点 3 的邻接点。
    • 从辅助数组中判断对应的邻接点是否被访问过。
    • 接下来就到了 5 号结点了,将 5 号结点的值改为 1.

在这里插入图片描述

  1. 访问到顶点 5 时,发现它的两个邻接点都被访问过了,此时就往后退,直到退到顶点 1 时,发现顶点 1 还有个邻接点 4 没被访问过,走 忽略。
    • 然后从顶点 4 开始,去访问 6 号顶点,并将 visited[6] 的值改为1.

在这里插入图片描述
在这里插入图片描述

  1. 到了顶点 6 时发现它的邻接点都被访问过了,此时就往后退,直到退到起点时,发现辅助数组中的元素都是1,此时遍历结束。

在这里插入图片描述

邻接矩阵深度优先算法

void DFS(AMGraph G,int v)//图 G 为邻接矩阵类型
{
		visit(v);//访问第 v 个顶点
		visited[v] = 1;访问之后立即修改辅助数组元素
	
		for(w = 0;w < G.vexnum;w++)//从v所在行从头检索邻接点
		{
				//找邻接矩阵中值不为0,且辅助数组中值为0的点,然后从这个点出发继续去遍历
				if((G.arcs[v][w] != 0)&&(!visited[w]))
				{
						DFS(G,w);//w是v的邻接带你,如果w未访问,则递归调用DFS
				}
		}
}

DFS算法效率分析

假设图中有 n 个顶点,e 条边

  • 邻接矩阵来表示图,遍历图中每一个顶点都要从头扫描该顶点所在行,时间复杂度是 O(n2)
  • 邻接表来表示图,虽然有 2e 个表结点,但只需要扫描 e 个结点即可完成遍历,加上访问 n 个头结点的时间,时间复杂度为 O(n+e)

结论

  • 稠密图适于在邻接矩阵上进行深度遍历。
  • 稀疏图适于在邻接表上来进行深度遍历。

广度优先搜索(BFS)

算法思想

仿树的层次遍历,从一个顶点开始去访问它的所有邻接点。

遍历方法

  1. 从图中的某个顶点 V 出发。
  2. 依次访问该结点的所有邻接点 Vi1,Vi2,…Vin。
  3. 再按照这些顶点被访问的先后次序依次访问与它们相邻接的所有未被访问的顶点。
    • 重复此过程,直到左右顶点均被访问为止。

例如

  1. 从顶点 V1 出发,访问 V1。
  2. 依次访问 V1 的各个未曾访问过的顶点 V2 和 V3。
  3. 依次访问 V2 的邻接点 V4 和 V5 ,以及 V3 的邻接点 V6 和 V7,最后访问 V4 的邻接点 V8。
  4. 由于这些顶点的邻接点均已被访问,并且图中所有的顶点都被访问,由此完成了图的遍历。得到的顶点访问序列为: V1->V2->V3->V4->V5->V6->V7->V8

在这里插入图片描述

再看个栗子

  1. 首先点亮入口处的灯,然后依次去点亮与这盏灯灯邻接的其余灯。

在这里插入图片描述
在这里插入图片描述

  1. 全部点亮之后再扩大一层,从这三盏灯开始,点亮与这三盏灯邻接的其余灯.

在这里插入图片描述

邻接表的广度优先算法

使用邻接表来进行遍历,任然需要一个辅助数组 visited[i] 来记录被访问的顶点。

在这里插入图片描述

访问一个点,然后接下来去访问它的邻接点,再然后去访问邻接点的邻接点,类似于树的层次遍历

  • 既然遍历方法类似于树的层次遍历,那么算法当然也可以。

在这里插入图片描述

算法步骤

广度优先算法需要借助队列

  1. 从图中某个顶点 V 出发,访问 V,并将visited[V] 的值置为1,然后将 V 进队。
  2. 只要队列不为空,则重复以下操作。
    • 队头顶点 u 出队,
    • 依次检查 u 的所有邻接点 w,如果visited[w] 的值为 0,则访问 w,并将 visited[w] 的值置为1,然后将 w 进队。

算法实现

//按照广度优先非递归遍历连通图 G
void BFS(Graph G,int v)
{
		cout << v;visited[v] = 1;//访问第v个顶点,并修改辅助数组对应位置的值为1
		InitQueue(Q);//将辅助队列Q初始化,置空
		EnQueue(Q,v);//将v进队
	
		while(!QueueEmpty(Q));//队列非空
		{
				DeQueue(Q,u);//将对头元素出队并置为u
					
				//依次检查 u 的所有邻接点 w,FirstAdjVex(G,u)表示u的第一个邻接点
				//NextAdjVex(G,u,w)表示u相对于w的下一个邻接点,w>=0表示存在邻接点
				for(W = FirstAdjVex(G,u);w >= 0;w = NextAdjVex(G,uw))
				{
						if(!visited[w])//w为u的尚未访问的邻接顶点
						{
								cout << w;//访问w
								visited[w] = 1;//将w在辅助数组中的值为1
								EnQueue(Q,w);//将w进队
						}
				}
		}
}

BFS算法效率分析

假设图中有 n 个顶点,e 条边

  • 如果使用邻接矩阵,则BFS对一每一个被访问到的顶点,都要循环检测矩阵中国的整整一行(n 个元素),总的时间代价为 O(n2)
  • 邻接表来表示图,虽然有 2e 个表结点,但是只需要扫描e个结点即可完成遍历,加上访问 n 个头结点的时间,时间复杂度O(n+e)

DFS与BFS算法效率比较

  • 空间复杂度相同,都是 O(n)(借用了堆栈和队列)。
  • 时间复杂度只与存储结构(邻接矩阵和邻接表)有关,而与搜索路径无关

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/174979.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UPS BP650CH实现nas自动关机

家里有个自己拼凑的nas需要防止断电不正常关机&#xff0c;因此购买了施耐德后背式BP650CH&#xff0c;之所以选这款是因为带了串口&#xff0c;串口终究还是很方便的东西。不管linux还是window还是其他系统都能够使用&#xff0c;通过串口直接获得ups的信息&#xff0c;就不需…

JDBC Maven MyBatis

文章目录JDBC&#xff08;Java Database Connectivity&#xff09;入门API详解DriverManger&#xff08;驱动管理类&#xff09;Connection(数据库连接对象)作用StatementResultSet&#xff08;结果集对象&#xff09;PreparedStatement连接池MavenMaven模型Maven 常用命令依赖…

简单二叉树的介绍

1.树的结构&#xff08;了解&#xff09;1.1概念树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0)个有限节点总成一个具有层次关系的集合。把它叫做树是因为它看起来像一颗倒挂的树&#xff0c;也就是说它的根是朝上&#xff0c;而叶子是朝下的&#xff08;本人…

工作玩手机识别监测系统 YOLOv5

工作玩手机识别监测系统通过YOLOV5网络深度学习算法模型对画面中人员玩手机行为进行实时监测&#xff0c;当识别到有人在玩手机行为时&#xff0c;无需人为干预立即抓拍存档触发告警。YOLO算法- YOLO算法是一种基于回归的算法&#xff0c;它不是选择图像中有趣的部分&#xff0…

WT588D语音芯片介绍

WT588D语音芯片简介WT588D 语音芯片是一款功能强大的可重复擦除烧写的语音单片机芯片。WT588D 让语音芯片不再为控制方式而寻找合适的外围单片机电路&#xff0c;高度集成的单片机技术足于取代复杂的外围控制电路。配套WT588DVoiceChip 上位机操作软件可随意更换WT588D 语音单片…

基于 docker 搭建 mysql5.7 主从复制

安装 docker 的教程可以看我的另一篇文章&#xff0c;拉取 mysql 镜像的步骤也在里面&#xff0c;在这不再重复&#xff1a;https://blog.csdn.net/wanzijy/article/details/128695674 1. 主机搭建 因为本人虚拟机中已经存在了 mysql &#xff0c;所以在使用镜像创建容器的时…

【论文翻译】End-to-End Human Pose and Mesh Reconstruction with Transformers

【cvpr论文】End-to-End Human Pose and Mesh Reconstruction with Transformers (thecvf.com) 【github】microsoft/MeshTransformer: Research code for CVPR 2021 paper "End-to-End Human Pose and Mesh Reconstruction with Transformers" (github.com) 摘要 我…

学习笔记:Java 并发编程③

若文章内容或图片失效&#xff0c;请留言反馈。 部分素材来自网络&#xff0c;若不小心影响到您的利益&#xff0c;请联系博主删除。 视频链接&#xff1a;https://www.bilibili.com/video/av81461839配套资料&#xff1a;https://pan.baidu.com/s/1lSDty6-hzCWTXFYuqThRPw&am…

在甲骨文云容器实例(Container Instances)上部署Ubuntu Desktop

甲骨文云推出了容器实例&#xff0c;这是一项无服务器计算服务&#xff0c;可以即时运行容器&#xff0c;而无需管理任何服务器。 今天我们尝试一下通过容器实例部署Ubuntu Bionic Desktop。 创建容器实例 在甲骨文容器实例页面&#xff0c;单击"创建容器实例"&…

Java 笔试题

Java 笔试题目录概述需求&#xff1a;设计思路实现思路分析1.java 面试题参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,wait for change,challenge Surviv…

分享151个PHP源码,总有一款适合您

PHP源码 分享151个PHP源码&#xff0c;总有一款适合您 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0c; 151个PHP源码下载链接&#xff1a;https://pan.baidu.com/s/1T_Hs4j0t39b-Y8UWHmAKyw?pwd7ao0 提取码&#…

论文浅尝 | DB4Trans:数据库内置知识图谱嵌入模型训练引擎

笔记整理&#xff1a;柳鹏凯&#xff0c;天津大学硕士发表期刊&#xff1a;计算机学报 第45卷Vol.45, 第9期 No.9链接&#xff1a;http://cjc.ict.ac.cn/online/onlinepaper/lpk-202297212908.pdf动机知识图谱嵌入技术主要将知识图谱中的实体和关系嵌入到连续的向量空间中&…

Centos Java1.8+Nginx+redis+pgsql 手工配置

一、系统升级&#xff0c;安装系统常用工具及配置 1.1 升级软件及Centos 内核 yum update -y yum clean all cat /etc/redhat-release 1.2 安装虚拟机守护进程 yum install qemu-guest-agent -y 1.3 安装系统常用工具包 yum install lrzsz vim wget dnf -y 1.4关…

2023牛客寒假算法基础集训营3 -- E-勉强拼凑的记忆(贪心 + 二分)

题目如下&#xff1a; 题解 or 思路&#xff1a; 我们可以发现&#xff1a;除了 n2n 2n2 无解&#xff0c; 其他情况答案至少为 n12\frac{n 1}{2}2n1​ 答案在 n12\frac{n 1}{2}2n1​ 到 nnn 之间 我们可以假设 答案为 ansansans 最优摆放为&#xff1a; 所以可以二分去求…

软件工程 黄金点游戏

这个故事最初出现在 《移山之道》中&#xff0c;我经常拿来做和创新的时机相关课堂练习和讨论&#xff0c;效果很好。我把这个练习和它的一些延伸话题都搬到这个新博客里。 黄金点游戏 N个同学&#xff08;N通常大于10&#xff09;&#xff0c;每人写一个 0~100之间的有理数 …

1、认识IntelliJ IDEA

文章目录1、认识IntelliJ IDEA1.1 JetBrains公司介绍1.2 IntelliJ IDEA介绍1.3 IDEA的主要优势&#xff08;对比Eclipse&#xff09;1.3.1 功能强大1.3.2 符合人体工程学1.4 IDEA的下载【尚硅谷】idea实战教程-讲师&#xff1a;宋红康 生活是属于每个人自己的感受&#xff0c;不…

Python:Docx文档模板创建使用

✨博文作者 wangzirui32 &#x1f496; 喜欢的可以 点赞 收藏 关注哦~~ &#x1f449;本文首发于CSDN&#xff0c;未经许可禁止转载 &#x1f60e;Hello&#xff0c;大家好&#xff0c;我是wangzirui32&#xff0c;今天我们来学习Docx文档模板创建与使用&#xff0c;开始学习吧…

2023新春祝福html代码,包你学会

前言大家新年好&#xff01;今天是年三十&#xff0c;在这个充满喜悦和欢乐的节日里&#xff0c;祝大家新年快乐。不论你在外面过的风生水起还是不尽人意&#xff0c;回到家一家人团团聚聚才是最好的。进入正题&#xff0c;我们作为IT民工&#xff0c;我们要用自己的方式表达对…

第三天总结 之 商品管理界面的实现 之 页面中 下拉框问题的解决

页面中下拉框问题的解决 在页面中 点击商品类型这个图标 会出现下拉框 展示所有的商品类型 然后通过选择的 类型 来作为 查询时的一个条件 即 当不选或选择展示所有商品时 按照 不对这个条件进行操作 选择其他的商品类型时 会查询出含有该类型的商品 下拉框中 数据的展示与 如…

java设计模式中责任链模式是什么/怎么用责任链模式避免if-else语句

继续整理记录这段时间来的收获&#xff0c;详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用&#xff01; 6.5 责任链模式 6.5.1 定义 职责链模式&#xff0c;为避免请求发生者与多个处理者耦合在一起&#xff0c;将所有请求处理者通过前一对象记住其下一对象的引用而连…