当前位置: 首页 > news >正文

DSA之图(3):图的遍历

文章目录

  • 0 图的遍历
  • 1 图的遍历方法
    • 1.1 深度优先搜索DFS
      • 1.1.1 DFS的思想
      • 1.1.2 邻接矩阵DFS的实现
      • 1.1.3 邻接矩阵DFS的代码实现
      • 1.1.4 非连通图的DFS遍历
      • 1.1.5 DFS算法效率分析
    • 1.2 广度优先搜索BFS
      • 1.2.1 BFS的思想(连通图)
      • 1.2.2 BFS的思想(非连通图)
      • 1.2.3 邻接表BFS的实现
      • 1.2.4 邻接表BFS的代码实现
      • 1.2.5 BFS算法效率分析
  • 2 DFS与BFS算法效率比较

0 图的遍历

在这里插入图片描述
实际上就是找出每个顶点的邻接点的过程。
在这里插入图片描述

1 图的遍历方法

图常用的遍历有两种方法:

  1. 深度优先搜索DFS
  2. 广度优先搜索BFS

1.1 深度优先搜索DFS

在这里插入图片描述
基本思路就是,一条路走到黑,走到无路可走就往回退,再检查是否有未走过的路(邻接点)。
(发现有邻接点未访问就去访问,直到所有邻接点都被访问)
在这里插入图片描述

1.1.1 DFS的思想

在这里插入图片描述
记住,往回退的时候只能走来的时候的路(原路返回)。

在这里插入图片描述
DFS很像树的先序遍历。

1.1.2 邻接矩阵DFS的实现

在这里插入图片描述

每个顶点只能访问一次,设置一个辅助数组Visted[i],开始的时候将数组初始化为0,所有顶点一开始都没访问过,访问过就设置1。
在这里插入图片描述
基本流程

假设,起点从 v 2 v_2 v2开始,并将其在辅助数组中的值改为1,接下来看 v 2 v_2 v2的没有被访问过的邻接点。怎么去找呢?查看邻接矩阵,行下标为2的,顺序去找。现在 v 2 v_2 v2的一个邻接点为 v 1 v_1 v1,正好 v 1 v_1 v1没有访问过(因为visited[1]=0),所以就可以往 v 1 v_1 v1那里走。到了 v 1 v_1 v1后,开始找 v 1 v_1 v1未访问的邻接点,按顺序来,首先找到了 v 2 v_2 v2,但是 v 2 v_2 v2此时被访问过了,不能访问,所以接着寻找,找到了 v 3 v_3 v3,没被访问过,就可以访问。到了几号,就要从几号出发,进行DFS。过了 v 3 v_3 v3找到了 v 5 v_5 v5没有访问,即走到了 v 5 v_5 v5。到了 v 5 v_5 v5发现 v 2 v_2 v2 v 3 v_3 v3都访问过了,所以进行回退,此时 v 5 v_5 v5是由 v 3 v_3 v3访问过来的,所以先回退到 v 3 v_3 v3,从哪来的就往哪里退,再接着从 v 3 v_3 v3访问,此时,与 v 3 v_3 v3相关的都被访问了,所以继续回退,回退到 v 1 v_1 v1继续进行DFS,发现 v 4 v_4 v4还没被访问,进行访问同时数组置1。到了 v 4 v_4 v4发现 v 6 v_6 v6还没被访问,所以进行访问。到了 v 6 v_6 v6发现邻接点都被访问了,所以往回退到 v 4 v_4 v4 v 4 v_4 v4往回退为 v 1 v_1 v1,还是都访问过,再回退到 v 2 v_2 v2,发现还是都访问过了,再发现visited[i]数组全是1,都访问过了,DFS结束。
在这里插入图片描述

1.1.3 邻接矩阵DFS的代码实现

void DFS(AMGraph G, int v) //图G为邻接矩阵类型
{cout << v;visited[v] = true; //访问第v个顶点for (w = 0; w < G.vexnum; ++w) //依次检查邻接矩阵v所在的行{if((G.arcs[v][w]!=0) && (!visited[w])){DFS(G, w);//w是v的邻接点,如果w未访问,则递归调用DFS}}
}

1.1.4 非连通图的DFS遍历

在这里插入图片描述
从任意一个顶点开始,找其未被访问的邻接点进行访问。当连通图的顶点都访问完后,再在其他的未被访问的顶点当中选一个点进行访问,进行DFS。

1.1.5 DFS算法效率分析

在这里插入图片描述

1.2 广度优先搜索BFS

在这里插入图片描述

1.2.1 BFS的思想(连通图)

首先从一个点开始(假设就是入口的那个点),访问其所有的邻接点,如下所示:
在这里插入图片描述
都点亮之后,再扩大一层,即找邻接点的邻接点,直到所有点都被访问。
在这里插入图片描述
在这里插入图片描述

1.2.2 BFS的思想(非连通图)

在这里插入图片描述
也是从一个顶点出发,访问其邻接点,之后再找邻接点的邻接点。接下来找非连通的部分,未访问的顶点中任取一个来访问。
在这里插入图片描述

1.2.3 邻接表BFS的实现

在这里插入图片描述

需要一个visited[i]数组来表示点是否被访问。
其实现过程,访问顺序与树的层次遍历有点像。在树的层次遍历当中,是用队列来实现的,加入节点,加入其孩子,加入其孩子的孩子,以此类推;而邻接表当中是加入节点,加入其邻接点,加入其邻接点的邻接点,以此类推。

实现过程
0号位置即 v 1 v_1 v1入队,在队尾,队尾指针移动一下,visited[0]相应的置1,代表被访问过,之后队列中的0号出队,找其邻接点并入队。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如何找 v 1 v_1 v1的邻接点?在邻接表中进行寻找,第一个单链表就是。发现了1号位置的 v 2 v_2 v2和2号位置的 v 3 v_3 v3,被访问了,数组相应位数置1,且入队。在这里插入图片描述
被访问后就出队,出队到 v 2 v_2 v2,找其邻接点3号也就是 v 4 v_4 v4,进行入队置1,接下来又找到了4号也就是 v 5 v_5 v5,进行入队置1。
在这里插入图片描述
在这里插入图片描述
现在 v 2 v_2 v2顶点的两个邻接点都入队了。接下来就下一个,2号 v 3 v_3 v3为队头,出队,开始找其邻接点。找到了5号6号,即 v 6 v_6 v6 v 7 v_7 v7
在这里插入图片描述
之后再看3号即 v 4 v_4 v4的邻接点,为7号 v 8 v_8 v8,加入进来。在这里插入图片描述
之后访问4号 v 5 v_5 v5的邻接点。将 v 5 v_5 v5的两个邻接点入队,但是1号和7号都入队了,所以忽略。
所以接着访问5号 v 6 v_6 v6发现其邻接点都访问过了。之后看6号的邻接点,也是都访问过了,之后看7号的邻接点,都访问过了。BFS结束。

1.2.4 邻接表BFS的代码实现

void BFS(Graph G, int v)//广度优先搜索
{cout << v;visited[v] = true; //访问第v个顶点InitQueue(Q, v); //辅助队列Q初始化,置空EnQueue(Q, v);//V进队while(!QueueEmpty(Q))//队列非空{DeQueue(Q, u); //队头元素出队并置为ufor (w = FirstAdjVex(G, u); w >= 0; w = NextAdjVex(G, u, w))if(!visited[w]) //w为u的尚未访问的邻接顶点{cout << w;visited[w] = true;EnQueue(Q, w); //w进队}}
}

1.2.5 BFS算法效率分析

在这里插入图片描述

2 DFS与BFS算法效率比较

空间复杂度

  • 空间复杂度相同,都是 O ( n ) O(n) O(n)(借用了堆栈或队列)

时间复杂度

  • 时间复杂度只与存储结构(邻接矩阵或邻接表)有关,而与搜索路径无关。邻接矩阵为 O ( n 2 ) O(n^2) O(n2),邻接表为 O ( n + e ) O(n+e) O(n+e)

相关文章:

DSA之图(3):图的遍历

文章目录 0 图的遍历1 图的遍历方法1.1 深度优先搜索DFS1.1.1 DFS的思想1.1.2 邻接矩阵DFS的实现1.1.3 邻接矩阵DFS的代码实现1.1.4 非连通图的DFS遍历1.1.5 DFS算法效率分析 1.2 广度优先搜索BFS1.2.1 BFS的思想&#xff08;连通图&#xff09;1.2.2 BFS的思想&#xff08;非连…...

从零开始学习 Java:简单易懂的入门指南之for循环(四)

java基础知识 流程控制语句1.1 流程控制语句分类1.2 顺序结构 判断语句&#xff1a;if语句2.1 if语句格式1练习1&#xff1a;老丈人选女婿练习2&#xff1a;考试奖励第一种格式的细节&#xff1a; 2.2 if语句格式2练习1&#xff1a;吃饭练习2&#xff1a;影院选座 2.3 if语句格…...

Android 之 http/https原理和机制

http---HyperTextTransfer Protocol 超文本传输协议 超文本-文本、HTML http的工作方式 c/b结构 如浏览器访问到服务器。 即发送请求->相应。 Url-Http报文 http://www.baidu.com/path 协议类型&#xff1a;http or https or websocket 服务器地址 BaseUrl 路径&…...

mybatis源码研究、搭建mybatis源码运行的环境

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、有兴趣的可以关注一手。 前提 研究源码、对我们的技术提高还是很有帮助的。简单的源码建议从mybatis入手。涉及到的设计模式不是很多。需要下载mybatis的源码和父工程依赖。注意下载的mybatis中的父工程依…...

【算法基础:搜索与图论】3.5 求最小生成树算法(PrimKruskal)

文章目录 最小生成树介绍朴素Prim算法算法思路⭐例题&#xff1a;858. Prim算法求最小生成树 Kruskal算法算法思路⭐例题&#xff1a;859. Kruskal算法求最小生成树 最小生成树介绍 最小生成树 有关树的定义 生成子图&#xff1a;生成子图是从原图中选取部分节点以及这些节点…...

扩展Ceph集群实现高可用

...

代码随想录 DAY45

class Solution { public: int climbStairs(int n) { vector<int>dp(n1,0); dp[0]1; for(int j0;j<n;j){ for(int i1;i<2;i){ if(j>i) dp[j]dp[j-i]; } } return dp[n]; } }; 这个题还是说想清楚 这个因为有1和2 阶的情况 所以i就是从1开始遍历 然后小于等于…...

Centos报错:[Errno 12] Cannot allocate memory

执行一个脚本刚开始正常&#xff0c;后面就报[Errno 12] Cannot allocate memory 如果内存不足&#xff0c;可能需要增加交换内存。或者可能根本没有启用交换。可以通过以下方式检查您的交换: sudo swapon -s如果它为空&#xff0c;则表示您没有启用任何交换。添加 1GB 交换…...

手把手教你怎么写顺序表

目录 一、顺序表有什么功能&#xff1f; 二、实现顺序表的各个功能 1.前置准备 2.初始化顺序表 3.顺序表扩容 4.打印顺序表 5.增加顺序表成员 5.1尾增 5.2头增 6.删除顺序表中成员的内容 6.1尾删 6.2头删 7.查找成员 8.修改(替换) 9.插入(在目标位置插入成员) 10.定…...

FPGA中RAM的结构理解

FPGA中RAM的结构理解 看代码的过程中对RAM的结构不是很理解&#xff0c;搞脑子一片浆糊&#xff0c;反复推算&#xff0c;好不容易理清了思路&#xff0c;记录下来&#xff0c;防止忘记。开辟的RAM总容量为128bytes&#xff0c;数据的位宽为32位&#xff08;即一个单元有32bit…...

家庭用的无线洗地机到底好不好用?2023洗地机品牌排行榜前十名

无线洗地机在清洁使用的时候非常便捷&#xff0c;多功能于一体能够轻轻松松就拖扫完全家&#xff0c;不需要多余的先扫再拖&#xff0c;浪费时间还非常的劳累。那么有什么靠谱并且质量也有保障的无线洗地机推荐吗&#xff1f;为了给想要选购洗地机的小伙伴提供一些参考&#xf…...

[React]常见Hook实现之useUpdateEffect

useUpdateEffect是一个自定义的React Hook&#xff0c;用于在组件更新时执行副作用。它的实现原理如下&#xff1a; useEffect和useLayoutEffect&#xff1a;useUpdateEffect内部使用useEffect或useLayoutEffect来注册副作用函数。这两个Hook函数都接受一个回调函数和依赖项数…...

为什么视频画质会变差,如何提升视频画质清晰度。

在数字时代&#xff0c;视频已经成为我们生活中不可或缺的一部分。然而&#xff0c;随着视频的传输和处理过程中的多次压缩&#xff0c;画质损失逐渐凸显&#xff0c;影响了我们对影像的真实感受。为了让视频画质更加清晰、逼真&#xff0c;我们需要采取一些措施来保护和修复视…...

【uni-app2.0】实现登录页记住密码功能

使用uni-app的uni.setStorageSync()和uni.getStorageSync()方法来存储和读取密码 在登录页中添加一个记住密码的u-checkbox选项&#xff0c;并在data里面添加一个rememberPwd的布尔值&#xff0c;在每次点击记住密码change的时候来记录用户的选择 <u-checkbox-group place…...

IDEA live templates

surround 在SQL的xml里 可以修改变量 官方文档 CDATA not null <if test"$SELECTION$ ! null and $SELECTION$ ! "> and $VAR1$ #{$SELECTION$} </if>not null like mysql <if test"$SELECTION$ ! null and $SELECTION$ ! "> and…...

电子鼻毕业论文

面向压埋探测的人体代谢气体识别方法的研究与应用 实现对非目标气体的检测 数据预处理 &#xff08;1a&#xff09;标准化 将采集到的数据先进行变换&#xff0c;统一数量级。其中&#xff0c;xij为第j个传感器的第i个采样值&#xff1b;xj为第 j 个气体传感器的所有采样值&…...

8 | 爬虫解析利器 PyQuery 的使用

文章目录 爬虫解析利器 PyQuery 的使用简介安装基本用法初始化查找元素遍历元素修改元素练习题练习题 1练习题 2答案练习题 1练习题 2总结爬虫解析利器 PyQuery 的使用 简介 PyQuery 是一个 Python 的库,它是 jQuery 的 Python 实现。PyQuery 可以让开发者使用类似于 jQuery…...

2023年 React 最佳学习路线

CSS CSS JavaScript JavaScript TypeScript 目前没有找到比其他文档好很多的文档地址 可以先看官网 React 新版 React 官方文档无敌 React React-router-dom V5 V6 Webpack webpack Antd antd...

使用 ChatGPT 进行研究的先进技术

在这篇文章中&#xff0c;您将探索改进您研究的先进技术。尤其&#xff0c; 分析和解释研究数据进行文献综述并找出研究差距废话不多说直接开始吧&#xff01;&#xff01;&#xff01; 分析和解释研究数据 一家小企业主希望分析客户满意度数据以改善客户服务。他们使用包含 10…...

Java-API简析_java.net.Proxy类(基于 Latest JDK)(浅析源码)

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/131881661 出自【进步*于辰的博客】 因为我发现目前&#xff0c;我对Java-API的学习意识比较薄弱…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

DBLP数据库是什么?

DBLP&#xff08;Digital Bibliography & Library Project&#xff09;Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高&#xff0c;数据库文献更新速度很快&#xff0c;很好地反映了国际计算机科学学术研…...

ThreadLocal 源码

ThreadLocal 源码 此类提供线程局部变量。这些变量不同于它们的普通对应物&#xff0c;因为每个访问一个线程局部变量的线程&#xff08;通过其 get 或 set 方法&#xff09;都有自己独立初始化的变量副本。ThreadLocal 实例通常是类中的私有静态字段&#xff0c;这些类希望将…...

DeepSeek越强,Kimi越慌?

被DeepSeek吊打的Kimi&#xff0c;还有多少人在用&#xff1f; 去年&#xff0c;月之暗面创始人杨植麟别提有多风光了。90后清华学霸&#xff0c;国产大模型六小虎之一&#xff0c;手握十几亿美金的融资。旗下的AI助手Kimi烧钱如流水&#xff0c;单月光是投流就花费2个亿。 疯…...