图遍历详解(C语言版)

article/2025/10/28 18:50:14

文章目录

  • 一、定义
  • 二、方法
    • 1、深度优先遍历
    • 2、广度优先遍历
  • 三、实现
    • 1、无向图或强连通有向图遍历
    • 2、非连通图遍历
  • 结语
  • 附录


一、定义

        从给定图中任意指定的顶点(称为初始点)出发,按照某种搜索方法沿着图的边访问图中所有顶点,使每个顶点仅被访问一次,这个过程称为图的遍历。如果给定图是连通的无向图或者是强连通的有向图,则遍历过程一次就能完成,并可按访问的先后顺序得到由该图的所有顶点组成的一个序列。

二、方法

        在遍历的过程中,从图的初始点到达图中的每个顶点可能存在多条路径。当沿着图中的一条路径访问过某顶点之后,可能还沿着另一条路径回到该顶点,即存在回路。为了避免同一个顶点被重复访问,需要设置一个访问标记数组visited,当顶点i,被访问过时,数组中的元素visited[i]置为1,否则置为0。
        图的遍历过程实际就是搜索过程,根据搜索方法的不同,图的遍历方法有两种:一种是深度优先遍历,另一种叫广度优先遍历。

1、深度优先遍历

        深度优先遍历的过程是从图中的某个初始点v出发,首先访问初始点v,然后选择一个与顶点v相邻且没被访问过的顶点w,以w为初始顶点,再从它出发进行深度优先遍历,直到图中与顶点v邻接的所有顶点都被访问为止,显然这是一个递归过程。
        下面给出一个示例:

在这里插入图片描述
        该图以A为初始点,从左往右通过深度优先遍历可以得到序列:ABDHECFG ,当然如果采取从右往左通过深度优先遍历可以得到序列:ACGFBEHD,可见采用深度优先遍历得到的序列并不是唯一的,这与建图时的存储有关,假如采用邻接表来存储,当每个顶点的邻接顶点采用头插法插入,那么之后采用深度优先遍历进行遍历时就会得到序列ACGFBEHD,当每个顶点的邻接顶点采用尾插法插入,那么之后采用深度优先遍历进行遍历就得到序列ABDHECFG。
        下面来看看深度优先遍历的代码

//深度优先遍历:  g:图  v:初始点    visited:标记数组
void DFS(GraphLnk *g, int v, bool visited[])
{//访问顶点,获取值,打印printf("%c-->",GetVertexValue(g,v));visited[v] = true;//为访问过的顶点做上标记int w = GetFirstNeighbor(g,GetVertexValue(g,v));//获取第一个邻接顶点while(w != -1){//当邻接顶点未被访问if(!visited[w]){DFS(g,w,visited);//以该顶点为起始顶点进行深度优先遍历}/*对第一个邻接顶点深度优先遍历完成,获取下一个邻接顶点的位置(如果该顶点未被访问,那么下一轮将以该顶点为起始顶点进行深度优先遍历)*/w = GetNextNeighbor(g,GetVertexValue(g,v),GetVertexValue(g,w));}
}

2、广度优先遍历

        广度优先遍历的过程是首先访问初始点v,接着访问顶点v的所有未被访问过的邻接点v1,v2,v3,…,vt,然后再按照v1,v2,v3,…,vt的次序访问每一个顶点的所有未被访问过的邻接点,依此类推,直到图中所有和初始点v有路径相通的顶点都被访问过为止。为了实现红色部分描述的先访问顶点的邻接顶点先访问,需要借用队列来实现。
        下面给出一个示例:

在这里插入图片描述
        该图以A为初始点,从左往右通过广度优先遍历可以得到序列:ABCDEFGH ,当然如果采取从右往左通过广度优先遍历可以得到序列:ACBGFEDH,可见采用广度优先遍历得到的序列也并不是唯一的,原因同深度优先遍历不唯一的原因,此处不再赘述。
        下面来看看广度优先遍历的代码

//广度优先遍历:g:图  v:初始点  visited:标记数组
void BFS(GraphLnk *g, int v, bool visited[])
{printf("%c-->",GetVertexValue(g,v));visited[v] = true;LinkQueue Q;//创建链队InitQueue(&Q);//初始化EnQueue(&Q,v);//将起始顶点入队int w;while(!Empty(&Q))//当队内还有顶点{GetHead(&Q,&v);//获取存在在队头的顶点vDeQueue(&Q);//出队//获取第一个邻接顶点w = GetFirstNeighbor(g,GetVertexValue(g,v));while(w != -1)//存在邻接顶点{if(!visited[w])//当该邻接顶点未被访问{//打印值printf("%c-->",GetVertexValue(g,w));visited[w] = true;//标记为已被访问EnQueue(&Q,w);//将该顶点入队,为之后访问该顶点的邻接顶点做铺垫}//获取顶点v的下一个邻接顶点(该邻接顶点的顺序在前面访问过邻接顶点w之后)w = GetNextNeighbor(g,GetVertexValue(g,v),GetVertexValue(g,w));}}
}

三、实现

        有了上面的理论基础,下面将基于图的邻接表存储来实现图的遍历,如果大家对图的邻接表存储方式还不太理解,那么可以先阅读图之邻接表详解(C语言版)此篇文章之后,再接着往下阅读。

1、无向图或强连通有向图遍历

        如果给定图是连通的无向图或者是强连通的有向图,则遍历过程一次就能完成,并可按访问的先后顺序得到由该图的所有顶点组成的一个序列。

        深度优先遍历实现

//深度优先遍历:给出遍历的图g和起始顶点vertex
void DFS(GraphLnk *g, T vertex)
{int n = g->NumVertices;//获取顶点个数//根据顶点数建立辅助数组空间:用来标记哪些顶点已经访问过,哪些顶点没有访问bool *visited = (bool*)malloc(sizeof(bool) * n);assert(visited != NULL);for(int i=0; i<n; ++i)//初始化标记数组{visited[i] = false;}//获取起始节点在邻接表中的位置int v = GetVertexPos(g,vertex);DFS(g,v,visited);//遍历free(visited);//释放辅助空间
}

        广度优先遍历实现

//广度优先遍历:给出遍历的图g和起始顶点vertex
void BFS(GraphLnk *g, T vertex)
{int n = g->NumVertices;//获取顶点个数//根据顶点数建立辅助数组空间:用来标记哪些顶点已经访问过,哪些顶点没有访问bool *visited = (bool*)malloc(sizeof(bool) * n);assert(visited != NULL);for(int i=0; i<n; ++i)//初始化标记数组{visited[i] = false;}//获取起始顶点在邻接表中的位置int v = GetVertexPos(g,vertex);BFS(g,v,visited);//遍历	free(visited);
}

2、非连通图遍历

        如果给定图是非连通图,则只能访问到初始点所在分量中的所有顶点,其他连通分量中的顶点是不可能访问到的,为此需要从其他每个连通分量中选择初始点,分别进行遍历,这样才能够访问到图中的所有顶点。

        深度优先遍历实现

//非连通图的深度优先遍历方式
void NonUnicomDFS(GraphLnk *g)
{int n = g->NumVertices;//获取顶点个数//根据顶点数建立辅助数组空间:用来标记哪些顶点已经访问过,哪些顶点没有访问bool *visited = (bool*)malloc(sizeof(bool) * n);assert(visited != NULL);for(int i=0; i<n; ++i)//初始化标记数组{visited[i] = false;}for(i=0; i<n; ++i) //遍历非连通图的顶点{if(!visited[i])//以没有访问的顶点为起始顶点进行深度优先遍历DFS(g,i,visited);}free(visited);
}

        广度优先遍历实现

//非连通图的广度优先遍历方式
void NonUnicomBFS(GraphLnk *g)
{int n = g->NumVertices;//获取顶点个数//根据顶点数建立辅助数组空间:用来标记哪些顶点已经访问过,哪些顶点没有访问bool *visited = (bool*)malloc(sizeof(bool) * n);assert(visited != NULL);for(int i=0; i<n; ++i)//初始化标记数组{visited[i] = false;}for(i=0; i<n; ++i) //遍历非连通图的顶点{if(!visited[i])//以没有访问的顶点为起始顶点进行广度优先遍历BFS(g,i,visited);}free(visited);
}

结语

        对图遍历的介绍就到这里啦,希望这篇文章能给予你一些帮助,感谢各位人才的:点赞、收藏和评论,我们下次见。

附录

        测试代码:图遍历详解(C语言版)


http://chatgpt.dhexx.cn/article/RbgZ5Kmv.shtml

相关文章

记录在遍历数据时,如何将数据的每一项中的个图片遍历出来

场景&#xff1a;商品评价页面&#xff0c;需将每一条评价显示出来&#xff0c;有图片评价的也要将图片显示出来 后端返回的接口数据格式如下&#xff1a; 如果是一张图片&#xff0c;在遍历外层的时候&#xff0c;用item.discuss_img就可以直接显示出来了&#xff0c;但多张图…

小程序轮播图遍历图片的方法

uniapp轮播图组件 方法一&#xff1a;直接使用图片 <swiper :indicator-dots"true" :autoplay"true" :interval"3000" :duration"1000" :circular"true"><swiper-item><image src"/static/swiper_img/…

图遍历算法

上一篇文章中我们简单介绍了什么是图和图分析&#xff0c;图分析的应用场景和优点&#xff0c;以及一些常用的图工具&#xff0c;这篇文章里将介绍一下简单的图遍历算法。 图的遍历 图的遍历是指&#xff0c;从给定图中任意指定的顶点&#xff08;称为初始点&#xff09;出发…

图的遍历(基础)

目录 一、图的遍历的相关定义 二、深度优先搜索 &#xff08;一&#xff09;深度优先搜索连通子图的基本思想 &#xff08;二&#xff09;采用递归的形式说明&#xff0c;则深度优先搜索连通子图的基本思想&#xff1a; &#xff08;三&…

图的遍历(深度优先遍历,DFS)

1.概念 图的遍历操作是从图中某一顶点出发&#xff0c;对图中所有顶点访问一次且仅访问一次 &#xff08;1&#xff09;在图中&#xff0c;遍历的起始顶点是编号最小的顶点 &#xff08;2&#xff09;某个起点到达不了所有顶点&#xff0c;则多次调用访问所有顶点 &#xf…

数据结构 第六章 图——图的遍历

6.5 图的遍历 在前面我们知道&#xff0c;树是一种非线性结构&#xff0c;为了方便它在计算机中的存储&#xff0c;对树进行遍历使它线性化。 而图同样也是一种非线性结构&#xff0c;但是图又是一种不同于树的多对多结构&#xff0c;所以在前面我们将其转换为了多个一对多的结…

数据结构——图(图的遍历)

图的遍历 图的遍历深度优先遍历&#xff08;DFS&#xff09;DFS算法效率分析深度优先遍历算法的实现广度优先搜索遍历&#xff08;BFS&#xff09;BFS算法效率分析DFS与BFS算法比较 图的遍历 遍历定义&#xff1a;从已给的连通图中某一顶点出发&#xff0c;沿着一些边访遍图中所…

图的遍历 (深度优先遍历和广度优先遍历)

一. 什么是深度优先遍历 深度优先遍历可定义如下&#xff1a;首先访问出发点v&#xff0c;并将其标记为已访问过&#xff1b;然后依次从v出发搜索v的每个邻接点w。若w未曾访问过&#xff0c;则以w为新的出发点继续进行深度优先遍历&#xff0c;直至图中所有和源点v有路径相通的…

图的遍历

图的遍历 介绍 是从图的某一顶点出发&#xff0c;按照某种搜索方式对图中所有顶点访问一次且仅一次。图的遍历可以解决很多搜索问题&#xff0c;在实际中应用非常广泛。图的遍历根据搜索方式的不同&#xff0c;分为广度优先搜索和深度优先搜索。 一.深度优先遍历 1.1介绍 深…

视频和图片合成软件,简单快速合成视频和图片

怎么把小视频和图片合成起来&#xff1f;有简单好上手的教程吗&#xff1f;今天就教大家简单几步&#xff0c;把视频和图片合成为照片视频。先看看用数码大师合成视频和图片的效果截图&#xff1a; 第一步&#xff1a;把图片一次性导入&#xff0c;为照片配上文字 点击“添加…

多张图片怎么合成gif?

多张图片怎么合成gif&#xff1f;gif动图是我们比较熟悉的一种网络聊天表情包&#xff0c;通常都是由图片或者视频转换而来的。很多小伙伴会选择用PS来制作GIF动图&#xff0c;但并不是所有小伙伴都会使用PS&#xff0c;所以一个自动简单&#xff0c;可以将图片或者视频直接转换…

android将图片做成视频播放,如何把图片做成视频【图文教程】

教你怎么将手机拍摄的一张张图片整合转换成视频播放更唯美。下面以直走婚纱mv电子相册为例。 安装好软件&#xff0c;先运行绿化程序&#xff0c;然后再运行软件&#xff0c;详情请参看使用说明txt文档。打开之后&#xff0c;有两个模式供你选择&#xff0c;左边是标准模式、右…

php把图片合成视频,如何把照片做成视频 照片音乐视频制作 并插入几段短视频片段...

如何把照片制作成视频&#xff1f;相信大家都已经有所耳闻了&#xff0c;把平时手机或者相机上拍摄的照片&#xff0c;还有拍摄的视频都可以合起来&#xff0c;再添加背景音乐就成了一个非常有纪念价值的视频了。然而已经不是只有照片和音乐的视频了&#xff0c;整个视频全是照…

视频转图片-人脸识别-合成视频

视频转图片-人脸识别-合成视频 代码&#xff1a; import cv2 import os,sys import numpy as npface_xml cv2.CascadeClassifier(r"C:\Users\lenovo\Desktop\python\jiqixuexi\haarcascade_frontalface_default.xml") eye_xml cv2.CascadeClassifier(r"C:\U…

怎样用计算机合并视频,电脑视频合并软件 , 怎样把多个视频合成为一个

昨天小编在搜梁博的歌曲《表态》的视频时(这首歌小编觉得真的很好听推荐下)在一个剪辑视频发现他将梁博在某综艺唱的歌曲全都剪辑在视频里。这里就运用到了一个剪辑视频知识&#xff0c;合并视频。既然看到小编就准备跟大家伙讲讲这个视频剪辑内容。如何把多个视频合并在一个视…

php合成视频特效,视频合并加转场效果

热爱视频后期剪辑的朋友都会知道&#xff0c;在视频的后期制作过程中&#xff0c;常见操作中就有视频合并这一项&#xff0c;及在视频之间加入转场效果&#xff0c;为影视编辑作品带来绚丽多彩的视觉效果&#xff0c;不禁会使人眼前一亮。接下来给大家介绍一款简易好用的视频编…

php 图片生成视频,图片转化为视频的方法 如何将照片制作成为视频

点击上方的下载地址&#xff0c;然后将软件进行安装。安装完毕后&#xff0c;打开软件在这个界面可以选择软件的比例大小和操作模式&#xff0c;我们选择“4:3”和“全功能模式”。 接着我们将要进行操作的图片导入到软件&#xff0c;点击“导入”后在“打开”界面选中所有的图…

ffmpeg使用(多个帧合成视频)

帧生成视频命令&#xff1a; ffmpeg -threads 2 -y -r 24 -i %05d.jpg output.mp4 视频生成帧命令&#xff08;按帧生成图片&#xff09;&#xff1a; ffmpeg -i checkpoints_dstt_car-turn_result.mp4 chaifen/%06d.png 1、下载ffmpeg安装包 https://github.com/BtbN/FFmpe…

matlab jpg合成gif,用MATLAB将照片合成视频或者GIF图片、以及Photoshop制作GIF图片

用MATLAB将照片合成视频或者GIF图片、以及Photoshop制作GIF图片 一、用MATLAB将照片合成视频(我使用的MATLAB是2015版本的) (1)、你需要需要合成视频的图片。 所有照片放在一个文件夹里面因为是使用Matlab的dir函数读取照片,所以读取时,你要先设置好文件名:图片名称按照“00…

FFmpeg初探——基于FFmpeg的图片合成视频

前言 商家在发布商品的时候&#xff0c;大部分情况下是没有视频的&#xff0c;这样往往会造成商品展示不全等问题&#xff0c;而视频制作又比较麻烦&#xff0c;为了解决此痛点&#xff0c;我们需要提供一键合成视频的功能。 之所以选择 FFmpeg&#xff0c;是因为我们期望后续能…