c++ 图的连通分量是什么_学习数据结构第五章:图(图的遍历操作)

第五章:图(图的遍历操作)

1.图的遍历

图的遍历:从图中某一顶点出发,按照某种搜索方法沿着图中的边对图中的所有顶点访问依次且仅访问一次

其实树的层次遍历和图的广度优先搜索类似,可以把这个二叉树看成一个图

ab7aa12d330c9eee506b32e40696835c.png

2.广度优先搜索(BFS)

广度优先搜索

  • 首先访问起始顶点v
  • 接着由v出发依次访问v的各个 未被访问过 的邻接顶点w1,w1....wi
  • 然后依次访问w1,w2....wi的所有 未被访问过 的邻接顶点
  • 在从这些访问过的顶点出发,访问它们所有 未被访问过 的邻接顶点
  • 以此类推
2fba1d8dffdc1ba611fd90dc9bee7012.png

如上图,它的 广度优先搜索遍历 ,我们如果按照 树的层次遍历 这种方式进行遍历它的过程如下:

首先 1,然后访问它的所有邻接顶点即 2,3,然后分别访问 2 和 3 的邻接顶点,2 的 4 和5 ,3 的 6 ,接着我们从顶点 4 出发依旧访问它的所有邻接顶点即 7 和 5,此时我们就会发生错误,因为顶点 5 我们已经访问过了,再访问就不符合 广度优先搜索 的要求了, 所以我们遍历的时候不能完全按照树的层次遍历的方式进行遍历图 ,那么怎么实现图的广度优先搜索呢?

我们知道树的层次遍历我们借助了一种特殊的数据结构:队列

那么图我们不仅仅要依靠队列还要依靠一个辅助标记数组即:队列+辅助标记数组

15115c2a44c1014e52b9d815399d504c.png
辅助标记数组
2fba1d8dffdc1ba611fd90dc9bee7012.png

我们依旧使用上面的图,首先我们需要初始化,即将辅助标记数组中的值全部置为0,即0表示未被访问,1表示已被访问。重新进行遍历:从 1 出发,首先 1 入队,接着修改 v[0]=1 ,接着出队队首元素 1 并访问,接着我们需要将 1 的邻接顶点 2 和 3 一次入队,接着修改 v[1]=1,v[2]=1 ,然后出队队首元素 2 并进行访问,接着我们需要将顶点 2 的邻接顶点分别 1,4,5进行入队,这里我们其实只入队了 4 和 5,接着修改 v[3]=1,v[4]=1 ,这里有一个判断过程就是利用这个辅助标记数组,接着出队队首队首元素 3 并访问,然后将顶点 3 邻接的顶点并且未入队的顶点进行入队操作,即顶点 6 入队,同时修改a[5]=1,接着出队队首元素 4 并访问,然后入队 顶点 4 的邻接的顶点并且未入队的顶点 7 ,同时修改 v[6]=1,接着出队队首元素 5 并访问,接着出队队首元素 7 并访问,接着出队队首元素 7 并访问,遍历完成。此时数组中所有顶点的值都是1.

代码实现

bool visited[MAX_TREE_SIZE] void BFSTraverse(Graph G){      for(int i=0; i        visited[i]=FALSE;    }    InitQueue(Q);    //for循环的作用,我们上面讲的是一个连通图,所有顶点都可以通过一个顶点依次进行访问    //但是如果一个图不是连通的,我们需要遍历所有顶点    for(int i=0;i        if(!visited(i)){            BFS(G,i);        }    }}//广度优先搜索void BFS(Graph G,int V){    visit(v); //访问    visited=TRUE; //TRUE 入队了,FALSE未入队    EnQueue(Q,v); //将结点入队    while(!isEmpty(Q)){ //判断队列是否是空        DeQueue(Q,v); //出队队首元素,并赋值到v中        //FirstNeighbor 求图G中顶点x的第一个邻接顶点,存在返回顶点号,不存在返-1        //判断 w是否大于0,如果是-1则说明没有邻接顶点了        //NextNeighbor 求图G中顶点v的的下一个邻接顶点并赋值给w        for(int w=FirstNeighbor(G,v);w>0;w=NextNeighbor(G,v,w)){             if(!visited[w]){//判断是否入队过                visit[w];                visited[w]=TRUE;                EnQueue(Q,w);            }        }    }}

3.应用

3.1无权图单源最短路径问题

定义从顶点u到顶点v的最短路径d(u,v)为从u到v的任何路径中最少的边数,若从u到v没有通路,则d(u,v)=∞(表示不可达到)

//和广度优先搜索相似,增加了保存最短路径的一个数组void BFS_MIN_Distance(Graph G,int u){//传入图 和 初始顶点    for(int i=0;i        d[i]=MAX; //保存最短路径的值,我们初始化为最大值    }    visited[u]=TRUE;//标识为该顶点已经入队    d[u]=0;//初始顶点路径值改为0    EnQueue(Q,u);//入队    while(!isEmpty(Q)){//判断队列时候为空    	DeQueue(Q,u);//出队队首元素        //FirstNeighbor 求图G中顶点x的第一个邻接顶点,存在返回顶点号,不存在返-1        //判断 w是否大于0,如果是-1则说明没有邻接顶点了        //NextNeighbor 求图G中顶点v的的下一个邻接顶点并赋值给w        for(int w=FirstNeighbor(G,u);w>0;w=NextNeighbor(G,u,w)){            if(!visit[w]){//判断该顶点是否已经被访问过                visited[w]=TRUE;//设置被访问过                //d[u]表示到初始顶点的最短路径,w是它的邻接点,所以+1等目前w到初始顶点的最短路径                d[w]=d[u]+1;                EnQueue(Q,w);//入队            }        }     }}

3.2广度优先生成树

广度优先生成树:在广度遍历过程中,我们可以得到一颗遍历树,称为广度优先生成树(生成森林)

如果是一个连通图我们会得到是一颗生成树,而如果是非连通图我们得到的是生成森林

连通图:任意两个结点都是连通的

ba6bddc3ed8e700793455103f318e4d9.png

邻接矩阵法的广度优先生成树是唯一的,邻接表法的不唯一

因为一个图的邻接矩阵表示是唯一的,所以我们在进行遍历的过程也是唯一的,但是邻接表表示法中我们输入的次序不唯一生成的边表就不唯一,对应遍历的过程(遍历边的次序)就不唯一了

4.深度优先搜索(DFS)

广度优先搜索和树层次遍历比较类似,而深度优先搜索和树先序遍历比较类似,如果把这样的一个树看成一个图,它的先序遍历顺序就是图的深度优先搜索遍历顺序

c641a52b3f169cfe9640bc14adc83568.png

我们可以发现广度优先搜索是按照图的宽度范围进行遍历,而深度优先搜索是按照一条路径的深度的走向进行搜索遍历的

深度优先搜索(DFS)

  • 首先访问起始顶点v
  • 接着由v出发访问v的任意一个邻接且未被访问的邻接顶点Wi
  • 然后再访问与Wi邻接且未被访问的任意顶点Yi
  • 若Wi没有邻接且未被访问的顶点时,退回到它的上一层顶点v
  • 重复上述过程,直到所有顶点被访问为止
2fba1d8dffdc1ba611fd90dc9bee7012.png

我们通过上面的算法思想遍历一遍上图:首先访问 1 ,接着可以任意访问顶点 2 或 3,我们访问 2,接着我们可以  访问任意顶点 4 或 5,我们访问 4 ,然后我们可以访问任意的顶点 7 或者 5 (7和5也是4的邻接顶点),假设我们访问5,然后 5 没有邻接且未被访问的顶点我们退回到 4 ,接着访问顶点 7,接着退回到顶点 1 ,然后访问顶点 3 ,接着访问 6,遍历完成:1 2 4 5 7 3 6

我们从上面的遍历过程可以发现整个过程可以使用递归来实现,当然递归也可以转换成来实现,同时我们也需要一个辅助标记数组。即:递归(栈)+辅助标记数组

代码实现

bool visited[MAX_TREE_SIZE]//辅助标记数组void DFSTraverse(Graph G){    for(int i=0;i        visited[i]=FALSE;//初始化所有结点都未必访问    }    for(int i=0;i        if(!visited[i]){//如果结点未被访问            DFS(G,i);//G:图,i:起始顶点的编号        }    }}void DFS(Graph G,int v){    visit(v); //访问    visited[v]=TRUE;//置为访问过    for(int w=FirstNeighbor(G,v);w>0;w=NextNeighbor(G,v,w)){            if(!visit[w]){//判断该顶点是否已经被访问过                DFS(G,w);//递归            }    }}
6fc15f5eff7814a67a9376d6af1d75e4.png

如上图,我们通过上面的代码来遍历一遍:从A出发,访问A并把A对应的辅助标记数组值设置为TREUE,接着我们找A的第一个邻接顶点比如是C,然后我们判断C没有被访问过,接着继续调用DFS函数,访问C,同理继续找C的第一个邻接顶点D,判断D没有被访问过,我们访问顶点D,然后D没有邻接顶点此函数结束,我们退回到访问C的顶点的DFS的for循环中,找到C的第二个邻接点E,判断E没有被方问过,我们访问E,接着E没有邻接顶点,继续退回到C,C没有未被访问过的邻接顶点,我们退回到A的DFS的for循环中,发现A的第二个邻接顶点E被访问过了,所以A也没有未被访问过的邻接顶点了,我们退回到了DFSTraverse函数的第二个for循环中,循环判断到B发现B为被访问,然后调用DFS函数,访问D,设为TRUE,然后发现B不存在未被访问的邻接顶点,所以退回到DFSTraverse函数的第二个for循环中,发现没有未被访问过的顶点了,所以遍历结束:ACDEB

从此过程可以看出第一个函数的作用就是如果我们的初始顶点无法完成遍历图中的所有顶点我们就可以通过循环遍历每一个顶点。

邻接矩阵法的DFS(BFS)序列唯一,邻接表法的不唯一

5.深度优先生成树

深度优先生成树:在深度遍历过程中我们可以得到一颗遍历树,称为深度优先生成树(生成森林)

a87e1563623d8e4710f8f9aaa7b8b1bb.png

邻接矩阵法的深度度优先生成树是唯一的,邻接表法的不唯一

6.遍历与连通性问题

如何通过遍历来判断该图的连通性?

2fba1d8dffdc1ba611fd90dc9bee7012.png

上面是一个无向图:无论我们使用BFS还是DFS都能通过任何一个顶点访问到其他的顶点,所以他是一个连通图

所以我们有以下结论:在无向图中,在任意结点出发进行一次遍历(调用一次BFS或者DFS),若能访问全部结点,说明该图是连通的。

21fab513cc4c7903625122c0993aa456.png

上面是一个非连通的无向图,我们在进行遍历(BFS或DFS)的时候为了遍历到每一个顶点,我们需要一个for循环对每一个顶点进行调用BFS或者DFS。

我们由此可以得到如下结论:在无向图中,调用遍历函数(BFS或DFS)的次数为连通分量的个数

8db39d1bf304813ad1b3f3a64657ca35.png

如上面是一个有向图:我们从顶点B出发DFS可以遍历到任何顶点,但是能访问到所有顶点代表这个图是一个强连通图吗?答案当然是不是的,能遍历到所有顶点只能说明从某个顶点到另一个顶点有一条有向突击。

如果上图我们从顶点A开始遍历,我们则需要调用两次DFS,所以在有向图中,调用遍历函数(BFS或DFS)的次数为不是强连通分量的个数

无向图叫连图,有向图叫强连通

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

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

相关文章

gson json转map_Java几种常用JSON库性能比较

点击上方“Java研发军团”,选择“置顶公众号”关键时刻,第一时间送达!阅读本文需要5分钟作者:飞污熊xncoding.com/2018/01/09/java/jsons.html本篇通过JMH来测试一下Java中几种常见的JSON解析库的性能。 每次都在网上看到别人说什…

计算机辅助设计工业产品cad竞赛试题,2017计算机辅助设计(工业产品CAD)赛项样题...

2017年全国职业院校技能大赛中职“计算机辅助设计(工业产品CAD)”赛项样题参赛选手须知1.比赛时间4小时,赛题共3大题4道题目,参赛选手需完成全部题目。2.参赛选手应始终保持赛题、图册完整,不得拆散赛题或图册。3.参赛选手须严格按照题目规定…

golang 捕获堆栈信息_【网络数据安全】为什么时间戳对于数据包捕获很重要

网络上发生的所有事件都是时间敏感的,这就是为什么在讨论数据包捕获和分析时,给数据包加上时间戳非常重要。此功能不仅可以防止和分析网络攻击,而且还能让你检查趋势和网络延迟。网络数据包时间戳可用于调查以某种方式影响网络性能的事件。例…

python语言的编程模式_一种基于Python语言的EDA开发平台及其使用方法与流程

本发明涉及EDA开发的技术领域,尤其是指一种基于Python语言的EDA开发平台及其使用方法。 背景技术: 目前,主流的EDA设计语言Verilog HDL能实现完整的芯片硬件逻辑电路开发,但是其代码密度低,可移植性和编程效率等等都存…

为什么只有奇次谐波_我们为什么要用UPS不间断电源?

所谓不间断电源系统,就是当停电时能够接替市电持续供应电力的设备,它的动力来自电池组,由于不间断电源反应速度快,停电的瞬间在4~8毫秒内或无中段时间下继续供应电力。为什么要用UPS不间断电源?现在全世界各国的大众供…

计算机一般的应用课题方向,计算机类哪个方向的课题好立项

课题申报计算机类哪个方向的课题好立项时间:2020年01月17日 所属分类:课题申报 点击次数:计算机技术如今应用也是非常广泛的,很多计算机从业者也需要申报课题来评定职称,然而他们课题申报关心的问题也很多:…

angular语言前端开发_web前端开发入门全套学习方法路径,兼职在家做网站也能月入上万...

前端学习路径1.WEB前端快速入门在本阶段,我们需要掌握 HTML 与 CSS 基础,当然,也包含 H5 和 C3 的新特性。这个部分内容非常简单,而且非常容易掌握。相信你也更愿意学习这个部分,毕竟他可以让你最直观的感受到前端的魅…

bagging算法_集成算法——三个“臭皮匠”级算法优于一个“诸葛亮”级算法

最近在打算法竞赛的时候用到了集成算法,效果还不错,索性就总结了一篇集成算法的文章,希望能帮到正在转行的数据分析师们。集成算法核心思想集成算法的核心思想是通过构建并结合多个学习器来完成学习任务,也就是通俗意义上的三个“…

计算机u盘驱动坏了如何的修复,U盘识别不了,小编教你U盘识别不了怎么修复

最近收到一个用户的提问,他说新买了了一个U盘,用了没几天,就发现电脑识别不了U盘。不像是U盘坏了,相信用过u盘的朋友遇到过U盘无法识别的情况吧,对于怎么解决这个问题,每个人都各有说辞,各种方案…

python读取html_从零开始的Python爬虫教程(一):获取HTML文档

前言:在上一节从零开始的Python爬虫教程(零):粗识HTML结构中,粗略给大家介绍了一下HTML文档,是为了在接下来的教程中让大家更容易理解和掌握。在接下来的教程中,需要大家提前安装python3.x版本,…

cmd长ping记录日志和时间_四个网络命令ping、arp、tracert、route的详细用法

网络相关的从业人员,都需要面对检测和解决网络故障的各种问题,实际案例中因为网络导致的故障也是最多的,今天我们和大家一起来学习一下解决网络故障时使用最多的四个网络命令。希望对大家以后的实际工作中的故障排除起到作用。1、Ping命令的用…

计算机d盘给c盘,win10 c盘与d盘都是主分区如何将d盘空间分给c盘

在安装win10系统的时候,用户都喜欢将硬盘分为多个主分区盘符,可是在使用过程中,发现win10系统中c盘空间越来越小,因此就想要将d盘空间分一些给c盘,那么win10系统c盘与d盘都是主分区时如何将d盘空间分给c盘呢&#xff1…

大学计算机用的笔记本,推荐一款大学生用笔记本电脑

现在的大学生,基本上都会购买一台适合适合自己的电脑。但是市面上那么多品牌,要怎么选择呢?下面是小编整理的详细内容,一起来看看吧!大学生用笔记本电脑推荐一、惠普ENVY 13这款惠普笔记本电脑只有13英寸,外…

数字图像处理技术详解程序_大学专业详解系列135——数字媒体技术(工学学士)...

数字媒体技术(工学学士)毕业生应具备的知识和能力(1)系统掌握数字媒体技术专业的基本理论、基础知识和基本技能;(2)掌握数字影视技术、数字影视制作技术的理论与方法,能熟练运用拍摄、编辑、特效制作等技巧创作数字影视作品;(3)掌握网络传播的…

乐高收割机器人_乐高圣诞45002作品来啦!——驯鹿拉雪橇、圣诞树、圣诞棒棒糖...

圣诞节快乐圣诞系列作品第五弹来袭大家好我是zfeng老师,今天我们继续来圣诞节系列作品吧!有粉丝朋友留言说希望出一起用百变工程系列积木搭建的圣诞主题作品,今天它来了,wedo、ev3的作品也已经安排接下来会陆续更新。闲话不多说啦…

w7系统关闭打印服务器,w7打印后台处理程序服务总是自动停止如何解决【照片】...

今天我要向您介绍的是,此w7打印后台处理程序服务始终会自动停止. 怎么解决呢?如何解决此问题,我将向您介绍具体的解决方案.计算机系统推荐下载: 雨林木风win7系统下载具体解决方案:1. 打印机服务启动设置开始打印服务要启动和查看打印服务&am…

域服务器怎么修改管理员密码,域服务器更改客户端管理员的密码

域服务器更改客户端管理员的密码 内容精选换一换管理员应定期修改Kerberos管理员“kadmin”的密码,以提升系统运维安全性。修改此用户密码将同步修改OMS Kerberos管理员密码。已在集群内的任一节点安装了客户端,并获取此节点IP地址。cd /opt/hadoopclien…

.classpath文件有什么用_干货分享:Windows目录结构剖析,C盘目录常见文件夹都有什么用?...

我们天天和文件夹打交道,但是有好多的碍眼的文件夹我们能不能删除呢,来看看今天的文章。先问一个问题,你对你电脑的文件系统了解多少?很多人只管用,但是有些时候,想要自己清理一下文件的时候,不…

手机型号云服务器,手机型号查询接口

手机型号查询接口 内容精选换一换通过调用云手机服务提供的接口,您可以完整地使用云手机的所有功能。例如查询云手机列表、重启云手机、为云手机推送文件。华为云帮助中心,为用户提供产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问…

python counter_教你Python的collections.Counter类型

collections.Counter 类型可以用来给可散列的对象计数,或者是当成多重集合来使用 —— 多重集合就是集合里的元素可以出现多次1。collections.Counter 类型类似于其它编程语言中的 bags 或者 multisets2。(1)基本用法counter collections.Counter([生物, 印记, 考古…