数据结构之图的遍历

2023-11-10

什么是图的遍历

图的遍历是对一张图中所有节点进行访问的过程。在图遍历中,我们从图中的某个节点开始,沿着边一直访问其他节点,直到访问完所有与该节点有连通关系的节点。遍历过程中需要遵循一定的遍历规则,常见的有深度优先遍历和广度优先遍历。深度优先遍历是从某个节点开始,尽可能深地访问其他节点,直到到达图的最底层,然后再回溯到上一级节点继续遍历。广度优先遍历则是逐层访问节点,先访问与当前节点相邻的所有节点,然后再访问与这些节点相邻的节点,以此类推,直到访问完所有节点为止。

图的深度优先遍历

代码

#include <bits/stdc++.h>
#define MAX 100
using namespace std;
 
int Visited[MAX];
 
typedef struct{
	char vexs[MAX];        //顶点向量
	int arcs[MAX][MAX]; //邻接矩阵
	int vexnum,arcnum;      //顶点数,边数
}AMGraph;
 
 
int Location(AMGraph G, char c) {
	int i = 0;
	for(; i < G.vexnum; i ++) {
		if(G.vexs[i] == c) {
			return i;
		}
	}
	return -1;
}
 
void CreateUDG(AMGraph &G) {
	scanf("%d %d", &G.vexnum, &G.arcnum);
	int i = 0;
	getchar();
	for(i = 0; i < G.vexnum; i ++) {
		scanf("%c", &G.vexs[i]);
	}
	int j = 0;
	// 初始化 
	for(i = 0; i < G.vexnum; i ++) {
		for(j = 0; j < G.vexnum; j ++) {
			G.arcs[i][j] = 0;
		}
	}
	
	char c1, c2;
	int k = 0;
	getchar();
	for(i = 0; i < G.arcnum; i ++) {
		scanf("%c %c", &c1, &c2);
		getchar();
		j = Location(G, c1);
		k = Location(G, c2);
		G.arcs[j][k] = 1;
		G.arcs[k][j] = 1;
	}
}
 
void DFS(AMGraph G, int v) {
	int i = 0;
	cout << G.vexs[v] << ' ';
	Visited[v] = 1;
	for(; i < G.vexnum; i ++) {
		if(!Visited[i] && G.arcs[v][i] != 0) {
			DFS(G, i);
		}
	}
}
 
int main() {
	AMGraph G;
	CreateUDG(G); // 创建图 
	int v; // 从v开始遍历 
	cin >> v;
	DFS(G, v); // 深度优先搜索 
	return 0;
}

运行结果

在这里插入图片描述

分析

图的深度优先搜索(DFS)是从图中一个开始节点出发,沿着一条路径访问到不能再访问为止,然后回溯到该节点的上一个节点,继续搜索下一条路径,直到访问完所有与该节点连通的节点。DFS通常使用递归的方式实现,其基本思路如下:

  1. 访问该节点,并标记该节点为已访问。
  2. 对该节点的所有未被访问过的相邻节点,递归调用DFS。
  3. 回溯到上一个节点,重复第2步,直到所有节点都被访问过。

DFS算法的时间复杂度为O(|V|+|E|),其中|V|为节点数,|E|为边数。在实际应用中,DFS常用于有向图、无向图的连通性判断、拓扑排序、MST等问题。

值得注意的是,DFS可能会陷入死循环,因此需要在遍历过程中通过标记节点来避免重复访问。此外,DFS的搜索路径具有单向性,很可能并不是最短路径,因此适用于要求不需要最短路径的问题。如果需要求最短路径,可以使用广度优先搜索。

图的广度优先遍历

代码

#include <bits/stdc++.h>
#define MAX 100
using namespace std;
 
int Visited[MAX];
 
typedef struct{
	char vexs[MAX];        //顶点向量
	int arcs[MAX][MAX]; //邻接矩阵
	int vexnum,arcnum;      //顶点数,边数
}AMGraph;
 
 
int Location(AMGraph G, char c) {
	int i = 0;
	for(; i < G.vexnum; i ++) {
		if(G.vexs[i] == c) {
			return i;
		}
	}
	return -1;
}
 
void CreateUDG(AMGraph &G) {
	scanf("%d %d", &G.vexnum, &G.arcnum);
	int i = 0;
	getchar();
	for(i = 0; i < G.vexnum; i ++) {
		scanf("%c", &G.vexs[i]);
	}
	int j = 0;
	// 初始化 
	for(i = 0; i < G.vexnum; i ++) {
		for(j = 0; j < G.vexnum; j ++) {
			G.arcs[i][j] = 0;
		}
	}
	
	char c1, c2;
	int k = 0;
	getchar();
	for(i = 0; i < G.arcnum; i ++) {
		scanf("%c %c", &c1, &c2);
		getchar();
		j = Location(G, c1);
		k = Location(G, c2);
		G.arcs[j][k] = 1;
		G.arcs[k][j] = 1;
	}
}
 
void BFS(AMGraph G, int v) {
	printf("BFS from %d: ", v);
	int line[MAX] = {0};
	int front = 0;
	int rear = 0;
	int j = 0;
	printf("%c ", G.vexs[v]);
	Visited[v] = 1;
	line[rear ++] = v;
	while(rear != front) {
		int i = line[front ++];
		for(j = 0; j < G.vexnum; j ++) {
			if(!Visited[j] && G.arcs[i][j]) {
				printf("%c ", G.vexs[j]);
				Visited[j] = 1;
				line[rear ++] = j;
			}
		}
	}
}
 
int main() {
	AMGraph G;
	CreateUDG(G); // 创建图 
	int v; // 从v开始遍历 
	cin >> v;
	BFS(G, v); // 广度优先遍历 
	return 0;
}

运行结果

在这里插入图片描述

分析

图的广度优先搜索(BFS)是从指定的起点开始,沿着每条连接路径依次访问相邻的节点,直到所有节点都被访问。BFS使用队列来进行实现,其基本思路如下:

  1. 将起点加入队列,并标记该节点为已访问。
  2. 取出队列头部节点,对该节点的所有未被访问过的相邻节点,标记为已访问,并加入队列尾部。
  3. 重复第2步,直到队列为空。

BFS算法的时间复杂度同样为O(|V|+|E|),其中|V|为节点数,|E|为边数。BFS通常应用于计算最短路径、查找一组节点、遍历树等问题。

BFS搜索的路径具有层级性,最先访问到该节点的路径一定是最短的,因此适用于求解最短路径问题。此外,BFS的缺点是空间复杂度较高,需要使用队列进行存储,因此如果图的节点数比较大时,会占用较多的内存,可能导致程序执行缓慢。

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

数据结构之图的遍历 的相关文章

随机推荐

  • oracle failover mode,Oracle RAC FailOver配置

    Oracle RAC FailOver配置 Oracle RAC主要为数据库的应用提供了HA High Available 的环境 HA体现在负载均衡 loadbalance 和容错 failover 两个方面 Oracle RAC 的Fa
  • 机器学习---期望+方差+标准差+协方差

    1 期望 在概率论和统计学中 数学期望 mathematic expectation 或均值 亦简称期望 是试验中每次可能结果的概率乘以其结果的总和 是最基本的数学特征之一 它反映随机变量平均取值的大小 大数定律表明 随着重复次数接近无穷大
  • Optimal Coin Change(完全背包计数)

    题目描述 In a 10 dollar shop everything is worthy 10 dollars or less In order to serve customers more effectively at the cas
  • Java对象序列化

    Java 对象序列化 对象序列化的目标是将对象保存到磁盘中 或允许在网络中直接传输对象 对象序列化机制允许把内存中的 java 对象转换成为与平台无关的二进制流 从而允许把这种二进制流持久保存到磁盘上 实现对象序列化 该类实现接口 seri
  • texstudio与ctex_Latex的使用(Ctex+TeXstudio)

    1 下载 CTEX Latex 本来是只支持英文的 但是实在太好用了 遂结合中国的团队以及有识之士 开发了这个 CTEX CTEX 有 TexLive TexLive 为 Latex 安装包的名字 的所有内容 还包括了中文的支持 所以这里我
  • 【C++】详解inline

    2023年8月28日 周一晚上 目录 优点 缺点 使用条件 为什么调用函数会有开销 举例说明 优点 当使用inline关键字声明一个函数时 编译器会将函数体内联到所有调用该函数的地方 这可以提高执行效率 因为无需进行函数调用的开销 缺点 但
  • android 日期控件

    相关布局文件
  • android:OKHttp的使用

    1 之前学习了两种基于http访问服务器的方法 一种是HttpURLConenction 一种是Apache下的HttpClient 说实话 这两种方法操作起来都不是很简单明了 所以当前首选的网络通信库是由Square公司开发的OKHttp
  • 有关C++,Qt中使用指针的注意事项

    1 指针一般在创建的时候都应该初始化 除非你能保证要么你不会用到这个指针 要么在你使用之前它以及被被初始化了 如果不初始化 它就是野指针 在Debug模式下 VC 编译器会把未初始化的栈内存上的指针全部填成 0xcccccccc 当字符串看
  • RUNOOB python练习题6 斐波那契数列

    用来练手的python 练习题其六 原链接 python练习实例6 题干 斐波那契数列 斐波那契数列可以说是很好的递归理解工具了 这里就用递归实现一下斐波那契数列 源代码如下 返回fibonacci数列中某一项的数值 def Fibonac
  • 【面试题】2023年最新前端面试题-react篇

    原文见 语雀 https www yuque com deepstates interview hia3k3 核心概念 元素渲染 组件 props state refs 使用场景 如何创建 如何访问 组件通信 父子 祖孙 兄弟组件通信 生命
  • 【golang/go语言】Go语言代码实践——高复用、易扩展性代码训练

    某个项目里有一段老代码写的不是很好 想着能否通过自己掌握的知识 将其改善一下 感兴趣的小伙伴可以通过了解背景和需求 自己试想下该如何实现 如果有更好的方案也欢迎留言讨论 1 背景及需求 1 背景 假设我们的下游提供了一个定时任务接口Cron
  • linux编译命令——make -j18

    项目越来越大 每次需要重新编译整个项目都是一件很浪费时间的事情 Research了一下 找到以下可以帮助提高速度的方法 总结一下 1 tmpfs 有人说在Windows下用了RAMDisk把一个项目编译时间从4 5小时减少到了5分钟 也许这
  • Browsersync的安装及使用方法

    Browsersync介绍 Browsersync是浏览器同步测试工具 Browsersync能让浏览器实时 快速响应文件更改 html js css sass less等 并自动刷新页面 省去手动F5的事件 更重要的是 Browsersy
  • 模拟电路设计(24)---几种不同类型的A/D转换器的转换原理

    A D转换器是将模拟信号变换成相应的数字信号的装置 今天来介绍几种不同类型的A D转换器的转换原理 双积分式A D转换器的转换原理 这种转换本质是一种V T 电压 时间 的转换 如下图所示 它的一次转换基本工作原理可以分成三个工作阶段 双积
  • 为什么要学设计模式?

    01 什么是设计模式 设计模式 Design Pattern 代表了最佳的实践 通常被有经验的面向对象的软件开发人员所采用 设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案 这些解决方案是众多软件开发人员经过相当长一段时间的试
  • 亚马逊云科技 云技能孵化营——我的云技能之旅

    文章目录 每日一句正能量 前言 活动流程 后记 每日一句正能量 不能在已经获得足够多的成功时 还对自己的能力保持怀疑 露出自信的微笑 走出自信的步伐 做一个自信的人 前言 亚马逊云科技 Amazon Web Services 是全球云计算的
  • 事务的隔离级别

    脏读 脏读是指某一个事务读取到了其他事务未提交的数据 如果此数据回滚 将导致读取到的数据是错误的数据 不可重复读 指某个事务在开启后 读取某个范围或者某条数据时 在此事务未结束的时间里内 其他事务对表内的数据进行了添加 或者更改了某一条或者
  • 关于工作流应用的思考

    我今天在学习的过程中突然思考了一个问题 即工作流在多数企业中用不起来主要有两个原因 1 信息化程度不够 2 工作流不够灵活 下面我以大学业务管理为例 对以上两个原因进行说明 由于各个学院各个单位的系统相互独立 所以学院内部的工作通常由内部系
  • 数据结构之图的遍历

    什么是图的遍历 图的遍历是对一张图中所有节点进行访问的过程 在图遍历中 我们从图中的某个节点开始 沿着边一直访问其他节点 直到访问完所有与该节点有连通关系的节点 遍历过程中需要遵循一定的遍历规则 常见的有深度优先遍历和广度优先遍历 深度优先