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

【数据结构】图的深度优先遍历

一.图的遍历

图的遍历需要解决的关键问题

1.在图中,如何选取遍历的起始顶点?

从编号小的顶点开始

  • 在线性表中,数据元素在表中的编号就是元素在序列中的位置,因而其编号是唯一的。
  • 在树中,将节点按层序编号,由于树具有层次性,因而其层序编号也是唯一的。
  • 在图中,任何两个顶点之间都可能存在边,顶点时没有确定的先后次序的,所以,顶点的编号不唯一。

为了定义操作的方便,将图中的顶点安任意顺序排列起来,比如,按顶点的存储顺序。 

2.从某个起始点可能到达不了所有其它顶点,怎么办?

多次调用从某顶点出发遍历图的算法

3.因图中可能存在回路,某些顶点可能会被重复访问,那么如何避免不会因回路而陷入死循环呢?

附设访问标志数组visited[n] (n为结点个数)

4.在图中,一个顶点可以和其它多个顶点相连,当这样的顶点访问过后,如何选取下一个要访问的顶点呢?

  • 深度优先遍历
  • 广度优先遍历

二.深度优先遍历

1.基本思想

1)访问顶点v;

2)从v的未被访问的邻接点中选取一个顶点w,从w出发进行深度优先遍历;

3)重复上述两步,直至图中所有和v有路径相通的顶点都被访问到。

2.伪代码

  • 1.访问顶点v;visited[v]=1;
  • 2.w=顶点v的第一个邻接点;
  • 3.while(w存在)
  • 3.1 if(w未被访问)从顶点w出发递归执行该算法;
  • 3.2w=顶点v的下一个邻接点;

3.代码实现

3.1 邻接矩阵

template<class T>
void MGraph<T>::DFSTraverse(int v){bool visited[vertexNum]=false;//设置标志数组int w,i,count=0;cout<<vertex[v]<<endl;//访问顶点vvisited[v]=true;//标志数组置为true++count;//结点访问一次,计数器加一for(i=0;i<vertexNum;i++){if(arc[v][i]&&!visited[i]){//存在边且未被访问过w=i;//更新w的值DFSTraverse(w);//再次深度优先搜索w}if(count==vertexNum){//所有结点都被访问过,返回,减少执行次数return;}}}

3.2 邻接表

template <class T>
void ALGraph<T>::DFSTraverse(int v){int w,i=0,count=0;bool visited[vertexNum]=false;struct ArcNode *p=adjList[v].firstEdge;cout<<adjList[v].vertex<<endl;//访问节点vvisited[v]=true;//标志数组置为true++count;if(count==vertexNum){return;}while(p){if(!visited[p->adjvex]){w=p->adjvex;DFSTraverse(w);}else{p=p->next;}}
}

相关文章:

  • 参考文献格式
  • 【技术追踪】SAM(Segment Anything Model)代码解析与结构绘制之Mask Decoder
  • 蓝桥杯 map
  • 【数据库】数据库连接池导致系统吞吐量上不去-复盘
  • 麒麟 ZYJ 服务器软件适配 参考示例
  • openGauss学习笔记-124 openGauss 数据库管理-设置账本数据库-查看账本历史操作记录
  • 第五章 树和二叉树(上)【基本概念性质和二叉树遍历】
  • 算法升级之路(七)-盛最多水的容器
  • 2023-11-17 VsCode使用makefile进行多文件编译
  • 基于Element-Plus动态配置Menu 菜单栏
  • Windows Server 2012 R2系统服务器远程桌面服务多用户登录配置分享
  • 2023-11-18 Android Linux资源限制命令 ulimit,比如ulimit -d 是设置进程占用的最大数据段大小,默认是unlimited。
  • Spring Boot 中使用 ResourceLoader 加载资源的完整示例
  • python 计算最大回撤
  • 【六袆 - MySQL】SQL优化;Explain SQL执行计划分析;
  • ES6指北【2】—— 箭头函数
  • 【知识碎片】第三方登录弹窗效果
  • Android Volley源码解析
  • CSS选择器——伪元素选择器之处理父元素高度及外边距溢出
  • EOS是什么
  • ES6 学习笔记(一)let,const和解构赋值
  • Git的一些常用操作
  • laravel 用artisan创建自己的模板
  • mongodb--安装和初步使用教程
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • Nodejs和JavaWeb协助开发
  • PaddlePaddle-GitHub的正确打开姿势
  • Python中eval与exec的使用及区别
  • 产品三维模型在线预览
  • 大主子表关联的性能优化方法
  • 分布式事物理论与实践
  • 前端存储 - localStorage
  • 前端面试之闭包
  • 小程序开发中的那些坑
  • 优化 Vue 项目编译文件大小
  • const的用法,特别是用在函数前面与后面的区别
  • 基于django的视频点播网站开发-step3-注册登录功能 ...
  • ​Base64转换成图片,android studio build乱码,找不到okio.ByteString接腾讯人脸识别
  • ​比特币大跌的 2 个原因
  • ​一些不规范的GTID使用场景
  • #{} 和 ${}区别
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (145)光线追踪距离场柔和阴影
  • (2015)JS ES6 必知的十个 特性
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (八)Flask之app.route装饰器函数的参数
  • (七)Knockout 创建自定义绑定
  • (五)Python 垃圾回收机制
  • (原)记一次CentOS7 磁盘空间大小异常的解决过程
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • (原创) cocos2dx使用Curl连接网络(客户端)
  • (转)jdk与jre的区别
  • (转)大道至简,职场上做人做事做管理
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • .NET 8 编写 LiteDB vs SQLite 数据库 CRUD 接口性能测试(准备篇)