图的深度优先遍历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;
}

在这里插入图片描述

运行结果一致。

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

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

相关文章

MHA高可用-解决MySQL主从复制的单点问题

目录 一、MHA的介绍 1&#xff0e;什么是 MHA 2&#xff0e;MHA 的组成 2.1 MHA Node&#xff08;数据节点&#xff09; 2.2 MHA Manager&#xff08;管理节点&#xff09; 3&#xff0e;MHA 的特点 4. MHA工作原理总结如下&#xff1a; 二、搭建 MySQL MHA 实验环境 …

NoSQL之Redis

目录 一、关系型数据库与非关系型数据库 1.关系数据库 2.非关系数据库 2.1非关系型数据库产生背景 3.关系型数据库与非关系型数据区别 &#xff08;1&#xff09;数据存储方式不同 &#xff08;2&#xff09;扩展方式不同 &#xff08;3&#xff09;对事物性的支持不同 …

VSCode常用修改默认设置(settings.json)

❓ 问题1 我现在在vscode中鼠标选中某个单词&#xff0c;相同的单词都会自动出现一个高亮背景色&#xff0c;我需要怎么关闭这个功能呢&#xff1f; ⚠️ 注意 selectionHighlight 这个是鼠标双击后的高亮匹配&#xff0c;可以保留默认开启的配置&#xff0c;不用去改它。 …

智能革命:ChatGPT3.5与GPT4.0的融合,携手DALL·E 3和Midjourney开启艺术新纪元

迷图网(kk.zlrxjh.top)是一个融合了顶尖人工智能技术的多功能助手&#xff0c;集成了ChatGPT3.5、GPT4.0、DALLE 3和Midjourney等多种智能系统&#xff0c;为用户提供了丰富的体验。以下是对这些技术的概述&#xff1a; ChatGPT3.5是由OpenAI开发的一个自然语言处理模型&#x…

Git的简单入门使用

文章目录 拷贝项目的步骤创建项目的步骤提交项目或项目文件的步骤恢复项目文件的步骤 拷贝项目的步骤 找到需要用来存放项目的文件夹&#xff1b;在文件夹页面空白处右键点击&#xff0c;然后再菜单中选择“Open Git Bash here”。在Github上找到需要进行拷贝的项目&#xff0…

SpringMvc工作流程

用户通过浏览器发送请求到前端控制器DispatcherServlet。前端控制器直接将请求转给处理器映射器HandlerMapping。处理器映射器HandlerMapping会根据请求&#xff0c;找到负责处理该请求的处理器&#xff0c;并将其封装为处理器执行链HandlerExecutionChina后返回给前端控制器Di…

第33次CCF计算机软件能力认证

好菜。。而且这次是什么神仙打架&#xff0c;平均分居然201。。 不到一小时做完T1T2&#xff0c;之后一个小时做T4拿了30。剩下的时间做T3&#xff0c;没做出来&#xff08;哭了 看来是得练大模拟了&#xff08;痛苦~~>_<~~

Java中异常详解

文章目录 异常介绍存在形式程序中异常发生后的第一反应体系JVM的默认处理方案处理方式声明 throws概述格式抛出 throw格式注意意义 throws和throw的区别 捕获 try,catch介绍格式执行方式多异常捕获处理意义 如何选择用哪个 Throwable类介绍常用方法 自定义异常概述实现步骤范例…

Vulnhub:WESTWILD: 1.1

目录 信息收集 arp nmap nikto whatweb WEB web信息收集 dirmap enm4ulinux sumbclient get flag1 ssh登录 提权 横向移动 get root 信息收集 arp ┌──(root㉿ru)-[~/kali/vulnhub] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 0…

蓝桥杯—DS1302

目录 1.管脚 2.时序&官方提供的读写函数 3.如何使用读写函数 4.如何在数码管中显示在DS1302中读取出的数据&#xff1f; 1.管脚 2.时序&官方提供的读写函数 /* # DS1302代码片段说明1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 参赛选手可以自行…

分享一款实用的太阳能充电电路(室内光照可用)

随着物联网的发展&#xff0c;很多智能电子设备都朝着低功耗方向发展&#xff0c;光能&#xff0c;风能&#xff0c;机械能等不同的自然能源都能被利用起来作为电子设备的能量来源&#xff0c;本文要分享一款太阳能充电电路。 前言 大家好&#xff0c;我又来分享电路了&#…

基于顺序表的学生成绩管理系统

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;python从入门到精通&#xff0c;魔法指针&#xff0c;进阶C&#xff0c;C语言&#xff0c;C语言题集&#xff0c;C语言实现游戏&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持创作博文…