图的深度优先遍历DFS得到各节点的度

在 一文中,我们通过了广度优先搜索来得到图结构中各结点的度,
在这一篇文章中,我们要通过深度优先搜索来得到图结构中各结点的度。

初始化

初始化,在下面的代码中,我们创建了一个具有6个结点的图结构,以及使用邻接矩阵来表示图结构。

在这里插入图片描述

typedef struct Graph {          //创建图结构
	int values[8][8];         //图结构的邻接矩阵,权值为0意味两结点无路径
} Graph;
void FillGraph(Graph &g) {      //初始化出一个随机权值的图结构
	for(int i =0; i < 8; i++) 
		for(int j = 0; j < 8; j++)
			g.values[i][j] = 0;
	g.values[0][1]=1;
	g.values[1][0]=1;
	g.values[0][2]=1;
	g.values[2][0]=1;
	g.values[1][3]=1;
	g.values[3][1]=1;
	g.values[1][4]=1;
	g.values[4][1]=1;
	g.values[3][7]=1;
	g.values[7][3]=1;
	g.values[4][7]=1;
	g.values[7][4]=1;
	g.values[2][5]=1;
	g.values[5][6]=1;
	g.values[6][5]=1;
	g.values[2][6]=1;
	g.values[5][2]=1;
}

//展示图结构中各结点之间的权值 
void ShowValues(Graph g) {
	cout << "Values of each node:" << endl; 
	for(int i = 0; i < 8; i++) {
		cout<< i << ": ";
		for(int j = 0; j < 8; j++) {
			cout << g.values[i][j] << " ";
		}
		cout << endl;
	}
	cout<<endl;
} 

深度优先搜索DFS

深度优先搜索算法(Depth First Search,简称DFS)是一种用于遍历或搜索树或图的算法。

它的基本思想是尽可能深地搜索树的分支,当节点v的所在边都已经被探寻过或者在搜寻时结点不满足条件,搜索将回溯到发现节点v的那条边的起始节点。整个进程反复进行直到所有节点都被访问为止

通俗的讲,选定起始结点,随后一条路走到黑(走到没有路径时),返回原路,一旦有路就继续走,如此反复地得到遍历结果。

在这里插入图片描述
在这里插入图片描述

那么在这个图中,我们若以结点0为起始结点,那么遍历为

0 -> 1 -> 3 -> 7 -> 4 (此时只能再走去结点1,但是1已经遍历过了,因此要进行回溯)

回溯:4 - 7 (结点7没有连接无访问过的结点,因此还得再回溯)

​ 7 - 3, 3 - 1, 1- 0 ,(到达结点0时发现有无访问过的结点2)继续遍历

0 -> 2 -> 5 ->6 (回溯发现所有结点都已访问过,搜索结束)

倘若我们使用路径矩阵,即

int ans[8][8] = {{1, 2}, {3, 4}, {5, 6}, {1, 7}, {1, 7}, {2, 6}, {2, 5}, {3, 4}};

第n个一维数组意味着,结点n连接的结点。如ans[0] = {1, 2} 意味着 结点0 连接 结点1 和 结点2 。

那么我们的代码应当为:

#include <iostream>
#include <queue>
#include <vector>

using namespace std;
//图的路径矩阵
vector<vector<int>> adj = {{1, 2}, {3, 4}, {5, 6}, {1, 7}, {1, 7}, {2, 6}, {2, 5}, {3, 4}};
vector<bool> visited;//来记录结点是否被访问过
vector<int> ans;  //记录遍历得到的结点,其实也可以省略
int degree[8]; //记录数组的度数

void dfsDegree(int v) {
	ans.push_back(v);
	visited[v] = true;
	for (int u : adj[v]) {
		degree[v]++;
		if (!visited[u]) {
			dfsDegree(u);
		}
	}
}

int main() {
	visited = vector<bool>(8, false);
	for (int i = 0; i < 8; i++) {
		degree[i] = 0;
	}
	dfsDegree(0);
	for (int i : ans) {
		cout << i << " ";
	}
	cout << endl;
	cout << "DFS to Degrees of each node:" << endl;               //输出DFS遍历得到的结果
	for (int i = 0; i < 8; i++) {
		cout << "Node " << i << ": " << degree[i] << endl;
	}
	cout << endl;
	return 0;
}

通过运行结果可以得到通过DFS遍历的结果,以及各结点的度数。运行结果如下,

请添加图片描述

难点在于,如何通过邻接矩阵来进行深度优先遍历。

vector<vector<int>> iadj = {
	{0,1,1,0,0,0,0,0},
	{0,0,0,1,1,0,0,0},
	{0,0,0,0,0,1,1,0},
	{0,1,0,0,0,0,0,1},
	{0,1,0,0,0,0,0,1},
	{0,0,1,0,0,0,1,0},
	{0,0,1,0,0,1,0,0},
	{0,0,0,1,1,0,0,0}
};

深度优先遍历的思路是一样的,也就是说我们要修改for循环里面的条件,其他其实不用改动太多。

如通过递归、通过for循环遍历一个结点的相邻结点,判断是否访问过。

不同的是,如果是路径矩阵,for-each循环,得到的u直接就是结点,

而在邻接矩阵,我们如果还是for-each循环,得到的是1,如果要得到结点的话,就需要普通for循环了,用i来记录是哪个结点。

for循环代码为

for(int i = 0; i < 8; i++) {
		if(adj[v][i] == 0) continue;
		degree[v]++;
		if(!visited[i]) dfsDegree(i);
	}

完整代码如下:

#include <iostream>
#include <queue>
#include <vector>

using namespace std;
//图的路径矩阵
vector<vector<int>> adj = {
	{0,1,1,0,0,0,0,0},
	{0,0,0,1,1,0,0,0},
	{0,0,0,0,0,1,1,0},
	{0,1,0,0,0,0,0,1},
	{0,1,0,0,0,0,0,1},
	{0,0,1,0,0,0,1,0},
	{0,0,1,0,0,1,0,0},
	{0,0,0,1,1,0,0,0}
};
vector<bool> visited;//来记录结点是否被访问过
vector<int> ans;  //记录遍历得到的结点,其实也可以省略
int degree[8]; //记录数组的度数

void dfsDegree(int v) {
	ans.push_back(v);
	visited[v] = true;
	for(int i = 0; i < 8; i++) {
		if(adj[v][i] == 0) continue;
		degree[v]++;
		if(!visited[i]) dfsDegree(i);
	}
}

int main() {
	visited = vector<bool>(8, false);
	for (int i = 0; i < 8; i++) {
		degree[i] = 0;
	}
	dfsDegree(0);
	for (int i : ans) {
		cout << i << " ";
	}
	cout << endl;
	cout << "DFS to Degrees of each node:" << endl;               //输出DFS遍历得到的结果
	for (int i = 0; i < 8; i++) {
		cout << "Node " << i << ": " << degree[i] << endl;
	}
	cout << endl;
	return 0;
}

在这里插入图片描述

运行结果一致。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

YOLO电动车检测识别数据集:12617张图像,yolo标注完整

YOLO电动车检测识别数据集&#xff1a;12617张图像&#xff0c;电动车一类&#xff0c;yolo标注完整&#xff0c;部分图像应用增强。 适用于CV项目&#xff0c;毕设&#xff0c;科研&#xff0c;实验等 需要此数据集或其他任何数据集请私信

【调度工具】Azkaban用户手册

目录 一、概述 1.1 Azkaban 是什么 1.2 Azkaban 特点 1.3 Azkaban 与 Oozie 对比 功能 工作流定义 工作流传参 定时执行 资源管理 工作流执行 工作流管理 1.4 Azkaban 运行模式及架构 Azkaban 三大核心组件 Azkaban有两种部署方式 Azkaban Web Server Azkaban …

简约轻量-失信录系统源码

失信录系统-最新骗子收录查询系统源码 首页查询&#xff1a; 举报收录页&#xff1a; 后台管理页&#xff1a; 失信录系统 V1.0.0 更新内容&#xff1a; 1.用户查询,举报功能 2.界面独立开发 3.拥有后台管理功能 4.xss,sql安全过滤 5.平台用户查询 6.用户中心&#xff08;待完…

IO流:字节流、字符流、缓冲流、转换流、数据流、序列化流 --Java学习笔记

目录 IO流 IO流的分类 IO流的体系 字节流&#xff1a; 1、Filelnputstream(文件字节输入流) 2、FileOutputStream(文件字节输出流) 字节流非常适合做一切文件的复制操作 复制案例&#xff1a; try-catch-finally 和 try-with-resource 字符流 1、FileReader(文件字符…

JimuReport 积木报表

一款免费的数据可视化报表&#xff0c;含报表和大屏设计&#xff0c;像搭建积木一样在线设计报表&#xff01;功能涵盖&#xff0c;数据报表、打印设计、图表报表、大屏设计等&#xff01; Web 版报表设计器&#xff0c;类似于 excel 操作风格&#xff0c;通过拖拽完成报表设计…

C#学生信息管理系统

一、引言 学生信息管理系统是现代学校管理的重要组成部分&#xff0c;它能够有效地管理学生的基本信息、课程信息、成绩信息等&#xff0c;提高学校管理的效率和质量。本文将介绍如何使用SQL Server数据库和C#语言在.NET平台上开发一个学生信息管理系统的课程设计项目。 二、项…

前端学习<四>JavaScript基础——02-JavaScript入门:hello world

开始写第一行 JavaScript&#xff1a;hello world JS 代码的书写位置在哪里呢&#xff1f;这个问题&#xff0c;也可以理解成&#xff1a;引入 JS 代码&#xff0c;有哪几种方式&#xff1f;有三种方式&#xff1a;&#xff08;和 CSS 的引入方式类似&#xff09; 行内式&…

msyql 查看和修改字符集的方法

在插入或修改数据的时候&#xff0c;报字符集的错误&#xff0c;中文的无法进行插入修改。比如&#xff1a; update users set user_name关羽 where user_id2; 报错信息&#xff1a; ERROR 1366 (HY000): Incorrect string value: /xB9/xD8/xD3/xF0 for column user_name at …

2024年学浪视频下载器

学浪视频官方没有提供下载选项&#xff0c;但又有很多人需要学浪视频下载器&#xff0c;于是我就开发了这么一款软件&#xff0c;学浪视频下载器:小浪助手.exe 我把学浪下载器打包成压缩包&#xff0c;有需要的自己取一下 链接&#xff1a;https://pan.baidu.com/s/1y7vcqILT…

Google Chrome 常用设置

Google Chrome 常用设置 References 转至网页顶部 快捷键&#xff1a;Home 转至内容设置 chrome://settings/content 清除浏览数据 历史记录 -> 清除浏览数据 关于 Chrome 设置 -> 关于 Chrome chrome://settings/help References [1] Yongqiang Cheng, https:/…

保健品wordpress外贸模板

保健品wordpress外贸模板 健康保养保健品wordpress外贸模板&#xff0c;做大健康行业的企业官方网站模板。 https://www.jianzhanpress.com/?p3514

NucleiStudio下longan nano烧录官方例程

longan nano烧录官方例程 一、准备工作二、编译程序三、器件连接四、烧录程序 IDE:NucleiStudio202009 开发板:longan nano gd32vf103c8t6 一、准备工作 1、下载IDE 芯来科技官网下载NucleiStudio 2、下载烧录器 https://dl.sipeed.com/shareURL/LONGAN/LonganPi3H 网盘链接 …

达梦配置ODBC连接

达梦配置ODBC连接 基础环境 操作系统&#xff1a;Red Hat Enterprise Linux Server release 7.9 (Maipo) 数据库版本&#xff1a;DM Database Server 64 V8 架构&#xff1a;单实例1 下载ODBC包 下载网址&#xff1a;https://www.unixodbc.org/ unixODBC-2.3.0.tar.gz2 编译并…

【Qt 学习笔记】认识QtSDK中的重要工具

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 认识QtSDK中的重要工具 文章编号&#xff1a;Qt 学习笔记 / 03 文章目…

MySQL安装卸载-Linux

目录 1.概述 2.安装 2.1.上传 2.2.解压 ​​​​​​​2.3.安装 ​​​​​​​2.4.启动服务 ​​​​​​​2.5.查询临时密码 ​​​​​​​2.6.修改临时密码 ​​​​​​​2.7.创建用户 ​​​​​​​2.8.分配权限 ​​​​​​​2.9.重新链接 3.卸载 3.1.停…

A53 cache的架构解读

快速链接: 【精选】ARMv8/ARMv9架构入门到精通-[目录] &#x1f448;&#x1f448;&#x1f448; 引流关键词:缓存,高速缓存,cache, CCI,CMN,CCI-550,CCI-500,DSU,SCU,L1,L2,L3,system cache, Non-cacheable,Cacheable, non-shareable,inner-shareable,outer-shareable, optee、…

【C++】C++11类的新功能

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 默认成员函数 类成…

shell的编写

文章目录 1.框架2.命令行3.获取用户命令字符串4.命令行字符串分割5.执行命令和内建命令6.完整代码&#xff1a; 1.框架 我们知道shell是一直存在的&#xff0c;所以首先我们第一步就是要搭建一个框架&#xff0c;使其一直存在。 那么也很简单&#xff0c;一个while循环就可以完…

intellij idea 使用git的 cherry pick 摘取其他分支的comment

cherry pick 摘取其他分支的comment 如果想把 feature_v1.0 分支的comment 摘到 feature_v1.0_new 分支上&#xff0c; 先切换到 feature_v1.0_new分支&#xff0c;这一步不能少了。然后点击 下面菜单栏的 git&#xff0c;点击Local Changes旁边的 Log&#xff0c;这时能看到…

(科研实践篇)大模型相关知识

1.embedding 1.介绍&#xff1a; embedding就是用一个低纬的向量表示一个物品。而这个embedding向量的实质就是使距离相似的向量所对应的物品具有相似的含义&#xff08;参考皮尔逊算法和cos余弦式子&#xff1a;计算相似度&#xff09;简单来说&#xff0c;就是用空间去表示…