数据结构和算法之图的遍历

news2024/11/16 18:01:34

6.2 图的遍历

6.2.1 图的遍历——DFS

遍历:把图里面每个顶点都访问一遍而且不能有重复的访问

深度优先搜索(DFS)

当访问完了一个节点所有的灯后,一定原路返回对应着堆栈的出栈入栈的一个行为

深度优先搜索的算法描述

void DFS(Vertex V)//从迷宫的节点出来
{
visited[V] = true;//给每个节点一个变量,true相当于灯亮了,false则是熄灭状态
for(V的每个邻接点W)//视野看得到的灯
if(!visited[W])//检测是否还有没点亮的
DFS(W);//递归调用
}
//类似树的先序遍历
若有N个顶点、E条边,时间复杂度是
用邻接表存储图,有O(N+E)//对每个点访问了一次,每条边也访问了一次
用邻接矩阵存储图,有O(N²)//V对应的每个邻接点W都要访问一遍

6.2.2 图的遍历——BFS

广度优先搜索(Breadth First Search,BFS)

xx
void DFS(Vertex V)//从迷宫的节点出来
{
visited[V] = true;//给每个节点一个变量,true相当于灯亮了,false则是熄灭状态
for(V的每个邻接点W)//视野看得到的灯
if(!visited[W])//检测是否还有没点亮的
DFS(W);//递归调用
}
//类似树的先序遍历
若有N个顶点、E条边,时间复杂度是
用邻接表存储图,有O(N+E)//对每个点访问了一次,每条边也访问了一次
用邻接矩阵存储图,有O(N²)//V对应的每个邻接点W都要访问一遍

实例说明

第1步:访问A。

第2步:访问(A的邻接点)C。在第1步访问A之后,接下来应该访问的是A的邻接点,即"C,D,F"中的一个。

但在本文的实现中,顶点ABCDEFG是按照顺序存储,C在"D和F"的前面,因此,先访问C。

第3步:访问(C的邻接点)B。在第2步访问C之后,接下来应该访问C的邻接点,即"B和D"中一个(A已经被

访问过,就不算在内)。而由于B在D之前,先访问B。

第4步:访问(C的邻接点)D。在第3步访问了C的邻接点B之后,B没有未被访问的邻接点;因此,返回到

访问C的另一个邻接点D。

第5步:访问(A的邻接点)F。 前面已经访问了A,并且访问完了"A的邻接点B的所有邻接点(包括递归的邻

接点在内)";因此,此时返回到访问A的另一个邻接点F。

第6步:访问(F的邻接点)G。

第7步:访问(G的邻接点)E。

因此访问顺序是:A -> C -> B -> D -> F -> G -> E。

当然,上图是基于无向图,具体的代码在文章后面实现。

广度优先搜索

广度优先搜索算法(Breadth First Search),又称为"宽度优先搜索"或"横向优先搜索",简称BFS。

它的思想是:从图中某顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后分别从这

些邻接点出发依次访问它们的邻接点,并使得“先被访问的顶点的邻接点先于后被访问的顶点的邻接点被

访问,直至图中所有已被访问的顶点的邻接点都被访问到。如果此时图中尚有顶点未被访问,则需要另

选一个未曾被访问过的顶点作为新的起始点,重复上述过程,直至图中所有顶点都被访问到为止。

换句话说,广度优先搜索遍历图的过程是以v为起点,由近至远,依次访问和v有路径相通且路径长度为

1,2…的顶点。

实例说明

第1步:访问A。

第2步:依次访问C,D,F。在访问了A之后,接下来访问A的邻接点。前面已经说过,在本文实现中,顶点

ABCDEFG按照顺序存储的,C在"D和F"的前面,因此,先访问C。再访问完C之后,再依次访问D,F。

第3步:依次访问B,G。在第2步访问完C,D,F之后,再依次访问它们的邻接点。首先访问C的邻接点B,再

访问F的邻接点G。

第4步:访问E。在第3步访问完B,G之后,再依次访问它们的邻接点。只有G有邻接点E,因此访问G的邻

接点E。

因此访问顺序是:A -> C -> D -> F -> B -> G -> E。

6.2.3 图的遍历——为什么需要两种遍历

在不同的情况下效率不同

广度跟深度的区别

  • 1. 深度是直接一条路走到黑,碰壁没路走了在返回
  • 2. 广度是一圈一圈的扫描过去,虽然前面还有路也不会强行深入

6.2.4 图的遍历——图不连通怎么办

连通:如果从V到W存在一条(无向)路径,则称V与W是连通的

路径:V到W路径是一系列顶点{V,v1,v2,....,vn,W}的集合,其中任一对相邻的顶点间都有图中的边。

路径的长度是路径中的边数(如果带权(带权图),则是所有边的权重和)。如果V到W之间的所有顶点都不同, 则称为简单路径(有回路就不是简单路径)

回路:起点等于终点的路径

连通图:图中任意两顶点均连通

连通分量:无向图的极大连通子图

  • 1. 极大顶点数:再加1个顶点就不连通了
  • 2. 极大边数:包含子图中所有顶点相连的所有边

对有向图

//强连通:有向图中顶点V和W之间存在双向路径,则称V和W是强连通的(路径可以不同同一条,但是一定是连

通的)

//强连通图:有向图中任意两顶点均强连通

//强连通分量:有向图的极大强连通子图

//弱连通图:将强连通图的所有边的方向抹掉变成无向图就是连通的了

每调用一次DFS(V),就把V所在的连通分量遍历了一遍,BFS也一样

void DFS(Vertex V){
visited[V] = true;
for(V的每个邻接点W)
if(!visited[W])
DFS(W);
}

遍历分量

void ListComponents(Graph G){
for(each V in G)
if(!visited[V]){
DFS(V);//or BFS(V)
}
}

6.3 应用实例:拯救007

void Save007(Graph G)
{
for(each V in G){
if(!visited[V] && FirstJump(V)){//这个FirstJump(V)是007第一跳有没有可能从孤岛
跳到V上有没有可能,有且没踩过就跳上去
answer = DFS(V);//or BFS(V)
if(answer == YES) break;0
}
}
if(answer == YES) output("Yes");
else output("No");
}

DFS算法

void DFS(Vertex V)
{
visited[V] = true;//表示鳄鱼头踩过了
for(V的每个邻接点W)
if(!visited[W])
DFS(W);//递归
}

改良版本

void DFS(Vertex V)
{
visited[V] = true;//表示鳄鱼头踩过了
if(IOsSafe(V)) answer = YES;
else{
for(each W in G )
if(!visited[W] && Jump(V,W)){//可以从V jump跳到这个w上面,作用是算V到W之间的距
离是不是小于007可以跳跃最大距离
answer = DFS(W);//递归
if(answer == YES) break;
}
}
return answer;
}

6.4 应用实例:六度空间(Six Degrees of Separation)

理论:

  1. 你和任何一个陌生人之间所间隔的人不会超过6个
  2. 给定社交网络图,请对每个节点计算符合"六度空间"理论的结点占结点总数的百分比

算法思路

1.对每个节点进行广度优先搜索

2.搜索过程中累计访问的节点数

3.需要记录"层"数,仅计算6层以内的节点数

void SDS()
{
for(each V in G){
count += BFS(V);
Output = (count/N);
}
}
//结合最初的BFS
void BFS(Vertex V)
{
visited[V] = true;count = 1;
Enqueue(V,Q);//压到队列里
while(!IsEmpty(Q)){
V = Dequeue(Q);//每次循环弹出一个节点
for(V的每个邻接点W)
if(!visited[W]){//没有访问过的去访问将其压入队列中
visited[W] = true;
Enqueue(W,Q);count++;
}
}return count;
}

另外的解决方案

int BFS(Vertex V)
{
vistex[V] = true;count = 1;
level = 0;last = V;
Enqueue(V,Q);
while(!IsEmpty(Q)){
V = Dequeue(Q);
for( V的每个邻接点W)
if(!visited[W]){
visited[W] = true;
Enqueue(W,Q);count++;
tail = W;
}
if(V == last ){
level++;last = tail;
}
}
return count++;
}

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

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

相关文章

Redis面试篇

文章目录1 Redis与Memcache的区别?2 Redis的单线程问题3 Redis的持久化方案由哪些?4 Redis的集群方式有哪些?5 Redis的常用数据类型有哪些?6 聊一下Redis事务机制7 Redis的Key过期策略参考资料:为什么需要内存回收&…

SpringBoot+ElasticSearch 实现模糊查询,批量CRUD,排序,分页,高亮!

一、导入elasticsearch依赖 在pom.xml里加入如下依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>非常重要&#xff1a;检查依赖版本是否…

【图像隐写】DWT数字水印嵌入+攻击+提取【含Matlab源码 1759期】

⛄一、DWT数字水印简介 1 引言 数字水印技术发展迅速&#xff0c;出现了各种水印算法&#xff0c;最低有效位(Least Significant Bit,LSB)数字水印技术是最早的空域水印添加算法&#xff0c;它原理简单且易实现&#xff0c;但鲁棒性差。变换域水印算法大大提高了水印的鲁棒性&…

【微信小程序】博客小程序,静态版本(三)设计和开发首页、个人关于页

【博客小程序】专栏 【微信小程序】博客小程序&#xff0c;静态版本&#xff08;一&#xff09;准备工作 【微信小程序】博客小程序&#xff0c;静态版本&#xff08;二&#xff09;引入 lin-ui 组件、设计和开发文章页 【微信小程序】博客小程序&#xff0c;静态版本&#…

模型推荐丨政务大数据项目案例模型分享

主要工具&#xff1a;Python 技术大类&#xff1a;自然语言处理 主要业务问题&#xff1a; 在社会治理上&#xff0c;政府部门一般通过群众的意见反馈、舆论情绪&#xff0c;掌握社会现状&#xff0c;做好舆情工作&#xff0c;以促进社会长治久安。微博作为有着大量活跃用户…

13 Igress,集群进出流量的总管

文章目录1. 前言2. 为什么要有 Ingress?2.1 Service 的缺点2.2 (Ingress)怎么解决Service 的缺点&#xff1f;3. 为什么要有 Ingress Controller 和 IngressClass?3.1 为什么要有 Ingress Controller&#xff1f;3.1.1 Ingress Controller3.1.1 Ingress Controller 常见公司3…

深入学习Linux内核(二)体系结构简析

Linux内核体系结构简析 图1 Linux系统层次结构 最上面是用户&#xff08;或应用程序&#xff09;空间。这是用户应用程序执行的地方。用户空间之下是内核空间&#xff0c;Linux 内核正是位于这里。GNU C Library &#xff08;glibc&#xff09;也在这里。它提供了连接内核的系…

Jitter

1、Jitter定义 定义1&#xff08;SONET规范&#xff09; 抖动可以定义为数字信号在重要时点上偏离理想时间位置的短期变化。 Long term jitter 测量由参考点滞后相当数量的Cycle&#xff08;500~1000&#xff09;后时钟的抖动值。该抖动参数也是时钟稳定性的一个重要指标&a…

如何清除电脑缓存?让电脑运行速度提升的有效方法

随着时间的流逝&#xff0c;电脑保存太多缓存文件&#xff0c;电脑的运行速度会越来越慢&#xff0c;甚至无法启动。当出现这种情况时&#xff0c;我们就需要对电脑进行清理。那么如何清除电脑缓存&#xff1f;今天就来给大家分享几个方法&#xff0c;让你的电脑运行速度快起来…

Spark SQL 与 Hive 的小文件调优

文章目录小文件危害表的缓存shuffle 分区数调整Spark SQL 客户端设置合并Hive 客户端处理小文件合并小文件危害 小文件会造成 nn 处理压力变大&#xff0c;大大降低了读取性能&#xff0c;整个 HDFS 文件系统访问缓慢&#xff0c;大量的小文件还会导致 nn 内存溢出&#xff0c…

DataX使用、同步MySQL数据到HDFS案例

文章目录4. DataX使用4.1 DataX使用概述4.1.1 DataX任务提交命令4.1.2 DataX配置文件格式4.2 同步MySQL数据到HDFS案例4.2.1 MySQLReader之TableMode4.2.1.1 编写配置文件4.2.1.1.1 创建配置文件base_province.json4.2.1.1.2 配置文件内容如下4.2.1.2 配置文件说明4.2.1.2.1 Re…

jdk 11 自带的HttpClient

jdk 11 自带的HttpClient 文章目录jdk 11 自带的HttpClient步骤1&#xff1a;创建jdk HttpClient 对象步骤2&#xff1a;创建请求步骤3&#xff1a;使用client.sent()发送同步请求步骤4&#xff1a;处理响应下面是发送post请求&#xff0c;请求类型是json&#xff0c;使用clien…

汇智动力《软件测试课程V8.0版本》正式发布!

今年是汇智动力建校的第八个年头&#xff0c;这一路走来&#xff0c;我们始终抓住时代的机遇与发展同辉、与时代俱兴&#xff0c;助力千万学子圆梦互联网。时代在飞速发展&#xff0c;社会在不断进步&#xff0c;为了使汇智学子适应科技变化的需要&#xff0c;汇智动力《软件测…

限量版Spring实战笔记与其在收藏里吃灰,不如大家一起学习,欸 大家一起卷!

写在前面 作为一个java程序员&#xff0c;spring应该都不会陌生了吧&#xff1f; 对于大部分程序员来说&#xff0c;spring的入门&#xff0c;估计跑起一个框架&#xff0c;熟悉一下开发的流程&#xff0c;基本上就掌握spring框架的开发了。 随着开发年限的变大&#xff0c;我…

解决Netty那些事儿之Reactor在Netty中的实现(创建篇)-下

接上文解决Netty那些事儿之Reactor在Netty中的实现(创建篇)-上 Netty对JDK NIO 原生Selector的优化 首先在NioEventLoop中有一个Selector优化开关DISABLE_KEY_SET_OPTIMIZATION,通过系统变量-D io.netty.noKeySetOptimization指定&#xff0c;默认是开启的&#xff0c;表示需…

[附源码]计算机毕业设计疫情防控平台Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【OpenCV-Python】教程:3-14 Hough 圆变换

OpenCV Python Hough 圆变换 【目标】 学习用 Hough 变换检测圆cv2.HoughCircles() 【理论】 圆的数学表达式是 (x−xcenter)2(y−ycenter)2r2(x-x_{center})^2 (y-y_{center})^2 r^2 (x−xcenter​)2(y−ycenter​)2r2 其中 (xcenter,ycenter)(x_{center}, y_{center})…

[附源码]计算机毕业设计志愿者服务平台Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

matlab测量计算信号的相似度

本示例说明如何测量信号相似度。最近我们被客户要求撰写关于计算信号的相似度的研究报告&#xff0c;包括一些图形和统计输出。 将回答以下问题&#xff1a;如何比较具有不同长度或不同采样率的信号&#xff1f;如何确定测量中是否存在信号或仅有噪声&#xff1f;有两个信号…

校园论坛(Java)—— 考研学习模块

校园论坛&#xff08;Java&#xff09;—— 考研学习模块 文章目录校园论坛&#xff08;Java&#xff09;—— 考研学习模块1、写在前面2、系统结构设计2.1 各个页面之间的调用关系2.2. 登录注册模块各层的设计3、考研学习模块设计3.1 浏览和查看帖子3.2 发表帖子3.3 删除帖子3…