数据结构7.3_图的遍历

我们希望从图中某一顶点出发访遍图中其余顶点,且使每一个顶点仅被访问一次。

这一过程就叫做图的遍历

 

图的遍历算法是求解图的连通性问题拓扑排序求关键路径等算法的基础。

 

然而,图的遍历要比树的遍历复杂得多。

因为图的任一顶点都可能和其余的顶点相邻接。

所以,在访问了某个顶点之后,可能沿着某条路径搜索之后,又回到该顶点上。

为了避免同一顶点被访问多次,在遍历图的过程中,必须记下每个已访问过的顶点。

为此,我们可以设一个辅助数组visited[0...n-1],它的初始值置为“假”或者零,一旦访问了顶点vi,便置visted[i]为“真”或者为被访问时的次序号。

 

通常有两条遍历图的路径:深度优先搜索和广度优先搜索。

它们对于无向图和有向图都适用。

===================================================

深度优先搜索

(Depth First Search) DFS

这种遍历类似于树的先根遍历,是树的先根遍历的一种推广。

 

图(a) 是一张无向图

图(b)是深度优先搜索的过程

图(c)是广度优先搜索的过程

 

假设初始状态是图中所有顶点未曾被访问,则深度优先搜索可从图中某个顶点v出发,访问此顶点,然后依次从v的未被访问的邻接点出发深度优先遍历图,直至图中所有和v有路径相通的顶点都被访问到;

若此图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作为起点,重复上述过程,直至图中所有顶点都被访问为止。

为了在遍历过程中便于区分顶点是否已被访问,许附设访问标志数组visited[0 ... n-1],其初值为“false”,一旦某个顶点被访问,则其相应的分量置为“true”。

 

 1 Boolean visited[MAX];
 2 Status (*VisitFunc)(int v);
 3 
 4 void DFSTraverse(Graph G, Status(* Visit)(int v)) { //对图G作深度优先遍历
 5     VisitFunc = Visit;  //使用全局变量VisitFunc,使DFS不必设函数指针参数
 6     for(v=0; v<G.vexnum; ++v)  visited[v] = FALSE;  //访问标志数组初始化
 7     for(v=0; v<G.vexnum; ++v)
 8         if(!visited[w])  DFS(G, w);  //对尚未访问的顶点调用DFS
 9 
10 }
11 
12 
13 void DFS(Graph G, int v) {
14     //从第v个顶点出发递归地深度优先遍历图G
15     visited[v] = TRUE;
16     VisitFunc(v);  //访问第v个顶点
17     for(w = FirstAdjVex(G,v); w>=0; w=NextAdjVex(G,v,w))
18         if(!visited[w])  DFS(G, w);  //对尚未访问的邻接顶点w,递归调用DFS
19 
20 }

 

遍历的过程实际上是对每个顶点查找其邻接点的过程。其耗费的时间取决于所采用的存储结构。

当使用二维数组表示邻接矩阵作为图的存储结构时,查找每个顶点的邻接点所需时间为O(n^2),其中n为图中顶点数。

当以邻接表作为图的存储结构时,找邻接点所需时间为O(e),其中e为无向图中的边的书或有向图中弧的数。

因此当以邻接表作为存储结构时,深度优先搜索遍历图的时间复杂度为O(n+e)。

===================================================

广度优先搜索

(Breadth First Search) BFS 

广度优先搜索遍历类似于树的按层次遍历的过程。

 

假设从图中的某顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,

然后分别从这些邻接点出发依次访问它们的邻接点,并使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问,

直到图中所有已被访问的顶点的邻接点都被访问到。

若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作为起始点,重复上述过程,

直至图中所有顶点都被访问到为止。

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

 

例如对图a进行广度优先搜索遍历图如图c所示。

 

和深度优先搜索类似,在遍历的过程中也需要一个访问标志数组。

并且,为了顺次访问路径长度为2、3、...的顶点,需附设队列以存储已被访问的路径长度为1,2,...的顶点。

 

 

 1 void BFSTraverse(Graph G, Status(*Visit)(int v)) {
 2     //按广度优先非递归遍历图G。使用辅助队列Q和访问标志数组visited
 3     for(v = 0; v<G.vexnum; ++v)
 4         visited[v] = FALSE;
 5     InitQueue(Q);  //置空辅助队列Q
 6     for(v = 0; v<G.vexnum; ++v)
 7     {
 8         if(!visited[v])
 9         {
10             visited[v] = TRUE;
11             Visit(v);
12             EnQueu(Q, v)  //v入队列
13             while(!QueueEmpyt(Q)) {
14                 DeQueue(Q,u);      //队头元素出队并置为u
15                 for(w= FirstAdjVex(G,u); w>=0; w=NextAdjVex(G,u,w))
16                     if(!Visited[w]) { //w为u的尚未访问的邻接顶点
17                         Visited[w] = TRUE;
18                         Visite(w);
19                         EnQueue(Q,W);
20                     } 
21         }
22     }
23 
24 }

 

分析上述算法,每个顶点至多进一次队列。

遍历图的过程实质上通过边或弧找邻接点的过程。

因此广度优先搜索遍历图的时间复杂度和深度优先搜索遍历相同,两者不同之处仅仅在于对顶点访问的顺序不同。

 

转载于:https://www.cnblogs.com/grooovvve/p/10828044.html

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

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

相关文章

HCL实验四

PC端配置&#xff1a;配置ip地址 配置网关 交换机配置&#xff1a;①创建VLAN system-view vlan 10 vlan 20 ②配置PC端接口 interface vlan-interface 10 ip add 192.168.10.254 24 interface vlan-interface 20 ip add 192.168.20.254 24 转载于:https://www.cnblogs.com/zy5…

程序员/设计师能用上的 75 份速查表

本文由 伯乐在线 - 黄利民 翻译自 designzum。欢迎加入 技术翻译小组。转载请参见文章末尾处的要求。75 份速查表&#xff0c;由 vikas 收集整理&#xff0c;包括&#xff1a;jQuery、HTML、HTML5、CSS、CSS3、JavaScript、Photoshop 、git、Linux、Java、Perl、PHP、Python、…

GWAS: 网页版的基因型填充(genotype imputation)

在全基因组关联分析中&#xff0c;处理芯片数据时&#xff0c;必须走的一个流程就是基因型数据填充&#xff08;imputation&#xff09;。 当然&#xff0c;如果你拿到的是全测序的数据&#xff0c;请忽略这一步。 下面直奔主题&#xff0c;怎么在网页版进行基因型填充。 1 进入…

腾讯CKV海量分布式存储系统

摘要&#xff1a;腾讯CKV&#xff0c;是腾讯自主研发的高性能、低延时、持久化、分布式KV存储服务。在腾讯的微信平台、开放平台、腾讯云、腾讯游戏和电商平台广泛使用&#xff0c;日访问量超过万亿次。本文将全面剖析CKV的实现原理和技术挑战。 与Memcached和Redis等开源NoSQ…

编程之法:面试和算法心得

《编程之法&#xff1a;面试和算法心得》高清中文版PDF 含书目录 下载地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1Kcd2bRsIfhagKZR6NaOgXg 提取码&#xff1a;054s 《编程之法&#xff1a;面试和算法心得》高清中文版PDF高清中文版PDF 含书目录&#xff0c;36…

localStorage存、取数组

localStorage存储数组时需要先使用JSON.stringify()转成字符串&#xff0c;取的时候再字符串转数组JSON.parse()。 var arr[1,2,3,4];localStorage.setItem(key,arr);console.log(localStorage(key); //打印出字符串&#xff1a;1,2,3,4 正常存储&#xff1a;localStorage.setI…

Redis原理及拓展

Redis是单线程程序。单线程的Redis为何还能这么快&#xff1f; 1、所有的数据都在内存中&#xff0c;所有的运算都是内存级别的运算&#xff08;因此时间复杂度为O(n)的指令要谨慎使用&#xff09; 2、单线程操作&#xff0c;避免了频繁的上下文切换 3、多路复用&#xff08;非…

日常问题 - 远程服务器运行Tomcat出现卡顿阻塞

问题描述&#xff1a; 远程服务器Tomcat容器运行一个WEB项目&#xff0c;浏览器访问时&#xff0c;请求一直得不到响应&#xff0c;并且除此之外没有出现任何异常&#xff0c;像是被阻塞了。查看远程Tomcat窗口&#xff0c;也没有任何报错。鼠标在Tomcat窗口右键点击后&#xf…

给技术人上的管理课:平衡和集中

摘要&#xff1a;大中型团队管理是技术人转型的巨大挑战&#xff0c;这个阶段的管理工作&#xff0c;仍然可以归为技术范畴&#xff0c;依靠的大抵是管理人的筋肉力量。是否会管理&#xff0c;要看能否管好超出自己筋肉力量规模的团队。此中的关键&#xff0c;在于把握平衡和集…

理解分布式id生成算法--雪花算法(SnowFlake)

分布式ID生成算法的有很多种&#xff0c;Twitter的SnowFlake就是其中经典的一种。 注&#xff1a; 1B就是1个字节。Byte、KB、B、MB、GB之间的关系是&#xff1a;Bit——比特 &#xff1b; B ——字节&#xff1b;KB——千字节&#xff1b;MB——兆字节&#xff1b;GB——吉字节…

注解 @PostConstruct 与 @PreDestroy 详解及实例

简介 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Java EE5 引入了PostConstruct和PreDestroy这两个作用于Servlet生命周期的注解&#xff0c;实现Bean初始化之前和销毁之前的自定义操…

PHP 安装xdebug

xdebug官网: https://xdebug.org 安装步骤如下: 使用 phpinfo() 打印出PHP相关信息, 全选, 复制 打开 xdebug 网站: https://xdebug.org/wizard.php 在图中输入框中粘贴你复制的信息, 点击 Analyse my phpinfo() output 在结果中点击下载, 然后按照它提示的步骤进行操作即可…

分布式消息中间件 : Rocketmq

简述 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 分布式消息中间件&#xff0c;主要是实现分布式系统中解耦、异步消息、流量销锋、日志处理等场景。生产中用的最多的消息队…

消息中间件:RocketMQ 介绍(特性、术语、原理、优缺点、消息顺序、消息重复)

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 消息中间件的作用 1. 应用解耦 2. 异步处理 比如用户注册场景&#xff0c;注册主流程完成以后&#xff0c;需要调用邮件系统发送邮件…

使用 Intellij Idea 打包 java 工程为可执行 jar 包

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 其实还有个简单多了方法&#xff0c;见&#xff1a; 超简单方法&#xff1a; Intellij Idea 把 java 工程打成可运行的 jar 步骤&#x…

QuickStart系列:docker部署之Gitlab本地代码仓库

gitlab是可以在本地搭建的使用git作为源代码管理的仓库。 运行环境&#xff1a; win10vmware14docker7docker 1. 使用命令拉取镜像&#xff08;非必须&#xff0c;耗时比较久&#xff0c;这里以ce为准&#xff0c;ce是社区版&#xff0c;ee是企业版&#xff09;&#xff1a; do…

超简单方法: Intellij Idea 把 java 工程打成可运行的 jar

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 找到 Intellij Idea 最下面的 Terminal 选项&#xff0c;并点击进入该界面。 2. 在光标位置输入命令&#xff1a;mvn clean 。清理…

kafka集群搭建(消息)

1、Kafka使用背景在我们大量使用分布式数据库、分布式计算集群的时候&#xff0c;是否会遇到这样的一些问题&#xff1a;我们想分析下用户行为&#xff08;pageviews&#xff09;&#xff0c;以便我们设计出更好的广告位我想对用户的搜索关键词进行统计&#xff0c;分析出当前的…

[转]在Windows 下使用OpenCL

目前&#xff0c;NVIDIA和AMD的Windows driver均有支援OpenCL&#xff08;NVIDIA的正式版driver是从195.62版开始&#xff0c;而AMD则是从9.11版开始&#xff09;。NVIDIA的正式版driver中包含OpenCL.dll&#xff0c;因此可以直接使用。AMD到目前为止&#xff0c;则仍需要安装其…

docker 之 Dockerfile 实践

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 上一篇介绍了Dockerfile中使用的指令&#xff0c;现在开始进行指令实践 先查看下本地的镜像&#xff0c;选一个作为base image&#xf…