数据结构——图的深度优先遍历(DFS)

2023-11-18

  本文内图的存储方式是邻接矩阵。

  DFS的遍历方法可以类比树的先序遍历。

  

  在实现树的先序遍历时,遍历顺序是  根 子树 下一个子树 ...

  而DFS的实现方法是优先深度,与一个树按照先序遍历的顺序相同。

  所以在实现DFS之前,需要先学习   寻找第一个邻接点(FirstNeighbor) 寻找下一个邻接点(NextNeighbor) 如何实现

  这个在之前的实现广度优先遍历里有过分享,这里就不再赘述。我们就直奔主题。

BFS的实现

  图的深度优先遍历类比树的先序遍历。采取的遍历顺序为  结点 子节点 下一个子节点 ...

  我们可以采用递归的方法访问树的子树,那么也可以相同的方法进行图的深度优先遍历(DFS)

  不同的是我们需要设立一个 bool 变量 IsData 来进行判断,判断该变量是否被遍历过

  利用 for 循环和 if 判断来进行条件的筛选

  最后得到代码:

//DFS
void DFS(Adj_Matrix& q, char a)
{
	int m = find(q, a);
	if (m == -1)
		return;
	
	visit(q, m);
	q.IsData[m] = false;
	
	for (int i = FirstNeighbor(q, a); i > 0; i = NextNeighbor(q, a, i))
	{
		
		if (q.IsData[i])
		{
			DFS(q, q.data[i]);
		}

	}
}

  同样的,也需要考虑图为非连通图的情况,所以利用 for 循环对每一个连通分量进行遍历。

  最终得代码:

//非连通图DFS
void DFSTraverse(Adj_Matrix& q)
{
	for (int i = 0; i < q.NumData; i++)
		q.IsData[i] = true;

	for (int i = 0; i < q.NumData; i++)
		if (q.IsData[i])
			DFS(q, q.data[i]);
}


完整代码:

#include <iostream>
using namespace std;
#define MAX 10

//邻接矩阵
typedef struct Adj_Matrix
{
	//结点
	char data[MAX];

	//边
	int edge[MAX][MAX];

	//结点数
	int NumData, NumEdge;

	//判断结点有无被遍历
	bool IsData[MAX];

}Adj_Matrix;

//初始化
void InitAdj(Adj_Matrix& q)
{
	for (int i = 0; i < MAX; i++)
		q.IsData[i] = true;
	q.NumData = 0;
	q.NumEdge = 0;
}

//寻找位置
int find(Adj_Matrix q, char a)
{
	for (int i = 0; i < q.NumData; i++)
		if (q.data[i] == a)
			return i;
	return -1;
}

//寻找第一个临界点
int FirstNeighbor(Adj_Matrix q, char a)
{
	int m = find(q, a);
	if (m == -1)
		return -1;

	for (int i = 1; i <= q.NumData; i++)
		if (q.edge[m][i] == 1)
			return i;
	return -1;
}

//寻找下一个临界点
int NextNeighbor(Adj_Matrix q, char a, char b)
{
	int m = find(q, a);
	if (m == -1)
		return -1;

	int n = find(q, b);
	if (n == -1)
		return -1;

	for (int i = n + 1; i <= q.NumData; i++)
		if (q.edge[m][i] == 1)
			return i;

	return -1;
}

//遍历函数
void visit(Adj_Matrix q, int i)
{
	cout << q.data[i] << " ";
}

//DFS
void DFS(Adj_Matrix& q, char a)
{
	int m = find(q, a);
	if (m == -1)
		return;
	
	visit(q, m);
	q.IsData[m] = false;
	
	for (int i = FirstNeighbor(q, a); i > 0; i = NextNeighbor(q, a, i))
	{
		
		if (q.IsData[i])
		{
			DFS(q, q.data[i]);
		}

	}
}

//非连通图DFS
void DFSTraverse(Adj_Matrix& q)
{
	for (int i = 0; i < q.NumData; i++)
		q.IsData[i] = true;

	for (int i = 0; i < q.NumData; i++)
		if (q.IsData[i])
			DFS(q, q.data[i]);
}


int main()
{
	Adj_Matrix q;
	int j = 97;
	for (int i = 0; i < 4; i++, j++)
	{
		q.data[i] = (char)j;
	}
	q.edge[0][2] = q.edge[2][0] = q.edge[1][3] = q.edge[3][1] = q.edge[2][3] = q.edge[3][2] = 1;
	q.NumData = 4;
	q.NumEdge = 3;

	DFS(q, q.data[0]);
	cout << endl;
	DFSTraverse(q);

	return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构——图的深度优先遍历(DFS) 的相关文章

随机推荐

  • PageHelper+BootStrap+Vue+axios实现分页功能

    PageHelper BootStrap Vue axios实现分页功能 效果展示 技术栈 前端技术 Vue2 5 16 axios BootStrap3 3 7 后端技术 SpringBoot2 7 9 MyBatisPlus3 5 1
  • 数据库的导入

    1 进入到数据库 mysql uroot proot 2 创建数据库 create databases wms 3 进入到指定的数据库 use wms 4 设置数据格式 set names utf8 5 导入数据 source data m
  • Linux查看mysql数据库所在目录

    SQL语句 show global variables like datadir 如图所示 有什么不对的还望指正 书写不易 觉得有帮助就点个赞吧
  • 【算法-LeetCode】63. 不同路径 II(动态规划;滚动数组)

    63 不同路径 II 力扣 LeetCode 文章起笔 2021年11月13日16 28 08 问题描述及示例 一个机器人位于一个 m x n 网格的左上角 起始点在下图中标记为 Start 机器人每次只能向下或者向右移动一步 机器人试图达
  • 数据结构-输出单链表倒数第K个结点值

    问题描述 输入一个单向链表 输出该链表中倒数第k个结点 链表的最后一个结点是倒数第1个节点 输入形式 输入第一位为K值 其后接一串以空格分隔的整型值 输入 1时停止建立链表 输出形式 输出为倒数第K个结点的值 若无 则输出Not Found
  • 大数据分析Python中Scikit-learn机器学习库

    Scikit learn是一个免费的Python机器学习库 它具有多种算法 例如支持向量机 随机森林和k邻域 并且还支持Python数值和科学库 例如NumPy和SciPy 在大数据分析Python中Scikit learn机器学习库中 我
  • c++传递视频流到qml 的 VideoOutput

    c 传递视频流到qml 的 VideoOutput QT官方文档里面介绍的方法 Video Overview 继承QObject 实现属性 具有可读写videoSurface属性 Q PROPERTY QAbstractVideoSurfa
  • 2023年,真正的智慧楼宇大脑什么样?建立可视化的智慧楼宇舒适化模型

    一 什么是智慧楼宇大脑 人一辈子 有30000天 而待在楼内的时间 有24000天 智慧楼宇是以建筑物为平台 以通信技术为主干 利用系统集成的方法 将计算机技术 网络技术 自控技术 软件工程技术和建筑艺术设计有机地结合起来 打通各个孤立系统
  • 允许Widget接受拖拽的数据

    实现向widget中拖拽数据并获取数据的方法 1 首先要给widget设置接受拖拽的属性 2 安装事件过滤器 过滤拖拽事件 ui widget gt setAttribute Qt WA AcceptDrops ui widget gt i
  • IDC首份国内电子签约报告:法大大市场份额第一

    日前 IDC 国际数据公司 发布了两份关于中国电子签约市场的报告 中国电子签约软件市场份额报告 2019 和 中国电子签约软件市场预测报告 2020 2024 这是IDC进入中国以来 首度针对国内电子签约市场启动的独立研究 报告显示 从市场
  • 【渗透测试学习】—记录一次自测试渗透实战

    写在前面 本文是作者入门web安全后的第一次完整的授权渗透测试实战 因为最近在总结自己学习与挖掘到的漏 无意中翻到了这篇渗透测试报告 想当初我的这篇渗透测试报告是被评为优秀渗透测试报告的 故在此重新整了一下 分享一下自己的思路与骚操作给大家
  • 卡拉赞服务器延迟,卡拉赞开荒详细功略(前门)

    卡拉赞开荒详细功略 猎手阿图门 无论别人告诉你这个副本有多么简单 对于一个开荒团队来说 这些说法都没有多大意义 简单是胜利者的宣言 但不是功略里该出现的字眼 这份功略尽最大可能提到了每个BOSS的许多细节 希望对你加速开荒进程能够有所帮助
  • hostnamectl 主机名管理

    在linux中修改主机名称是经常使用的 主机名称可以很轻松的识别服务器 centos7系统新增了hostnamectl命令 root hostname hostnamectl h h help 显示帮助 version 显示安装包的版本 t
  • 【论文阅读笔记】Learning Spatio-Temporal Representation with Pseudo-3D Residual Networks

    代码地址 https github com ZhaofanQiu pseudo 3d residual networks 主要贡献 以经济且有效的方式构建了仿3D卷积神经网络模型 P3D ResNet 出发点 3D 卷积神经网络能够同时学习
  • java中nextln的作用_day8[逻辑运算符以及next]

    逻辑运算符 异或 一个数 同一个数两次 会得到原来的数字本身 a b b a a a b a b b a 字符串 字符使用单引号包裹起来的是字符 a 表示多个字符 ABCD 多个字符串 使用双引号包裹 称为字符串 数据类型String S大
  • nmi_watchdog功能测试及解析

    由 b178903294创建 最后修改于9月 23 2019 严格意义来讲nmi watchdog 属于中断检测范畴 是基于非屏蔽中断NMI的检测机制 是一种内核状态监护的狗 关于其介绍可参考nmi watchdog txt 1 2 NMI
  • OpenCV-Python (官方)中文教程(部分一)

    官网链接 英文版 https docs opencv org 4 1 1 d6 d00 tutorial py root html 第一章 OpenCV简介 了解如何在计算机上设置OpenCV Python 1 OpenCV Python教
  • 用在vscode快速FTP发布项目到服务器

    经常遇到前端项目 构建打包时候 需要好一会 构建结算后还用上传 往往这时候需要等待 所以就需要一个构建完项目然后自动上传到服务器目录 1 工具flashfxp 由于flashfxp支持命令行操作 所以我们选择来上传文件 在ftp站点管理里
  • DataGuard强制切换(failover)

    failover切换 执行以下步骤完成Data Guard环境的Failover切换 为了使 failover过程尽量不丢失数据 在执行真正的切换是要尽量处理主数据库到standby数据库redo日志的传输问题 并将它们注册到standby
  • 数据结构——图的深度优先遍历(DFS)

    本文内图的存储方式是邻接矩阵 FS的遍历方法可以类比树的先序遍历 在实现树的先序遍历时 遍历顺序是 根 子树 下一个子树 而DFS的实现方法是优先深度 与一个树按照先序遍历的顺序相同 所以在实现DFS之前 需要先学习 寻找第一个邻接点 Fi