首页 > 其他分享 >用邻接矩阵储存图(附带深度优先遍历DFS)代码解析

用邻接矩阵储存图(附带深度优先遍历DFS)代码解析

时间:2024-12-11 20:03:39浏览次数:8  
标签:遍历 arcs int DFS vexs AMGraph 邻接矩阵 顶点 Vnum

一、数据结构定义

代码中定义了结构体 AMGraph 来表示图。其中,Vnum 存储图的顶点数量,Anum 存储边的数量。vexs 是一个指向字符类型的指针,用于存储顶点信息,构成顶点表。arcs 是一个二维指针,指向整型类型,代表邻接矩阵,用于表示顶点之间的连接关系。结构体还包含析构函数 ~AMGraph(),其主要作用是在对象生命周期结束时释放动态分配的内存,包括 vexs 数组以及 arcs 二维数组的内存空间,以防止内存泄漏。

二、关键函数功能

  1. LocateVex 函数
    该函数用于在图中查找给定顶点 x 的下标。通过遍历 AMGraph 结构体中的顶点表 vexs,逐一比较顶点元素,若找到与 x 相等的顶点,则返回其对应的下标值。此函数为后续根据顶点信息操作邻接矩阵提供了索引依据。
  2. createVexs 函数
    此函数负责创建顶点表。依据 AMGraph 结构体中的顶点数量 Vnum,动态分配内存给 vexs 数组。随后利用循环,从标准输入读取顶点信息,并依次存储到 vexs 数组中,从而完成顶点表的构建。
  3. createArcs 函数
    用于创建邻接矩阵。首先根据顶点数量 Vnum 为 arcs 二维指针分配内存空间,以构建能够表示图中顶点连接关系的矩阵结构。接着将邻接矩阵中的所有元素初始化为 0,表示初始状态下各顶点间无连接。然后,按照输入的边信息,通过循环读取每一条边的两个顶点 Vbefore 和 Vbehind,借助 LocateVex 函数获取这两个顶点在顶点表中的下标,进而在邻接矩阵中将对应位置的元素设置为 1,以表示这两个顶点之间存在边连接。由于所处理的是无向图,所以需要在邻接矩阵的对称位置(即 arcs[Vbehind 下标][Vbefore 下标])也设置为 1。
  4. DFS_AM 函数
    这是深度优先搜索的核心函数。从指定的起始顶点 v 开始搜索过程。首先输出当前顶点 G.vexs[v],表示已访问该顶点,并在 visited 数组中将对应顶点的标记设置为 1。然后,通过循环遍历邻接矩阵的当前行(即与顶点 v 相关的连接关系),若发现与顶点 v 有边相连(G.arcs[v][i]!= 0)且目标顶点 i 尚未被访问(visited[i] == 0),则递归调用 DFS_AM 函数,以深度优先的策略继续探索与顶点 i 相连的其他顶点,直至无法继续深入或所有顶点均已被访问。

在 main 函数中,首先创建 AMGraph 图对象 G,并从标准输入读取图的顶点数量 Vnum 和边数量 Anum。接着依次调用 createVexs 函数和 createArcs 函数构建图的顶点表和邻接矩阵。随后创建并初始化 visited 数组,用于记录顶点的访问状态。最后,从顶点 0 开始调用 DFS_AM 函数进行深度优先搜索,并在搜索结束后释放 visited 数组的内存空间。

#include<iostream>
using namespace std;
typedef char VerTexType;
typedef int ArcType;

struct AMGraph
{
	int Vnum;  //点数
	int Anum;  //边数
	VerTexType* vexs;  //顶点表
	ArcType** arcs;  //领接矩阵

	~AMGraph()
	{
		delete[] vexs;
		for (int i = 0; i < Vnum; i++) {
			delete[] arcs[i];
		}
		delete[] arcs;
	}
};

//找到顶点下标
int LocateVex(AMGraph& G, VerTexType x)
{
	for (int i = 0; i < G.Vnum; i++) {
		if (G.vexs[i] == x)
			return i;
	}
}
//创建顶点表
void createVexs(AMGraph& G)
{
	//顶点表
	G.vexs = new VerTexType[G.Vnum];
	for (int i = 0; i < G.Vnum; i++) {
		cin >> G.vexs[i];
	}
}
//创建邻接矩阵
void createArcs(AMGraph& G)
{
	//领接矩阵
	G.arcs = new ArcType * [G.Vnum];
	for (int i = 0; i < G.Vnum; i++) {
		G.arcs[i] = new ArcType[G.Vnum];
	}
	for (int j = 0; j < G.Vnum; j++) {
		for (int k = 0; k < G.Vnum; k++) {
			G.arcs[j][k] = 0;
		}
	}

	VerTexType Vbefore, Vbehind;
	for (int i = 0; i < G.Anum; i++) {
		cin >> Vbefore >> Vbehind;
		G.arcs[LocateVex(G, Vbefore)][LocateVex(G, Vbehind)] = 1;
		G.arcs[LocateVex(G, Vbehind)][LocateVex(G, Vbefore)] = 1;
	}
}

void DFS_AM(AMGraph& G, int v,int*& visited)
{
	cout << G.vexs[v] << " ";
	visited[v] = 1;
	for (int i = 0; i < G.Vnum; i++) {
		if ((G.arcs[v][i] != 0) && (visited[i] == 0)) {
			DFS_AM(G, i,visited);
		}
	}
}

int main()
{
	AMGraph G;
	cin >> G.Vnum >> G.Anum;
	createVexs(G);
	createArcs(G);
	int* visited = new int[G.Vnum];
	for (int i = 0; i < G.Vnum; i++) {
		visited[i] = 0;
	}
	DFS_AM(G, 0, visited);

	delete[] visited;
	return 0;
}

标签:遍历,arcs,int,DFS,vexs,AMGraph,邻接矩阵,顶点,Vnum
From: https://blog.csdn.net/2401_84904048/article/details/144408764

相关文章

  • Python遍历文件夹及子文件夹
    importos#列出一个文件夹里的所有文件,文件夹defscan_dir_files(files):ifos.path.exists(files):#os.path.exists()判断文件或文件夹是否存在lst=os.listdir(files)print(lst)scan_dir_files('.')#执行函数#输出所有文件夹defdir_path......
  • P1463 [POI2001] [HAOI2007] 反素数 (DFS)
    题目链接:https://www.luogu.com.cn/problem/P1463找最大的g(x),如果最大值相同,x最小。由算数基本定理:数x的约数个数是∏(ci+1)。n最大是2e9,2^31>2e9,2*3*5*...*31>2e9。由此可知:1.ci之和一定不超过30;2.最大的质数不超过29。由贪心,要找不超过n的最大的反质数,选择的质数要尽量小,......
  • 105. 从前序与中序遍历序列构造二叉树
    问题描述分析逻辑上,从前序遍历中依次从前往后获取根结点,从中序里获取根结点的序号后可以获取左子树和右子树,递归构建树即可。分治/递归classSolution{public:vector<int>preorder;vector<int>inorder;unordered_map<int,int>um;//分治TreeNo......
  • 图常见算法大全( 三种遍历算法 + 三种最短路径算法 + 两种最小生成树)
    图的经典算法完整版万字原文见史上最全详解图数据结构一、图的遍历算法1.voidDFS(intstartVertex);2.voidBFS(intstartVertex);3.voidTopologicalSort();(两种实现方式)1.DFS(深度优先搜索)算法原理是一种用于遍历或搜索图(包括树)中节点的算法。其基本思想......
  • 【数据结构与算法】回溯算法:LeetCode“排列问题” 求解,解释并模拟递归+回溯的遍历过程
      【作者自述:记录学习笔记,既然写了就让更多的人看到吧!欢迎大家关注交流学习,一步一个脚印持续更新!】【更多推荐笔记】【数据结构与算法】动态规划:解密“完全背包问题”的真相!附LeetCode四大问题的实现-CSDN博客【数据结构与算法】动态规划:解密“0-1背包问题”的真相!附LeetC......
  • 【唐叔学算法】第十天:广度优先遍历-探索图结构的逐层之旅
    你是否曾为如何高效地解决图论中的搜索问题而苦恼?广度优先遍历算法,就像一位经验丰富的探险家,能帮你轻松探索图中的每个角落。今天,就让我们一起揭开广度优先遍历算法的神秘面纱,探索它在Java编程中的应用。一、什么是广度优先遍历?定义广度优先遍历是一种用于遍历或搜索图(Gr......
  • java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
    @目录java实现下载hdfs文件及文件夹说明:java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下1.下载xxx文件2.下载xx文件夹java实现下载hdfs文件及文件夹说明:java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下<!......
  • unit引擎渲染管线之场景遍历
    在Unity的渲染过程中,场景遍历是一个关键步骤,它直接影响到渲染性能和最终的视觉效果。以下是对场景遍历过程的详细说明,包括对象查找、剔除(Culling)以及后续处理的步骤。1.对象查找在每一帧渲染时,Unity会遍历场景中的所有GameObject,查找具有Renderer组件的物体。这个过程包......
  • 二叉树遍历
    前序顺序为根左右递归publicstaticvoidpreLoop(TreeNoderoot){System.out.println(root.value);if(root.left!=null){preLoop(root.left);}if(root.right!=null){preLoop(root.right);}}其他使用栈,以根右左的顺......
  • 【Leetcode Top 100】94. 二叉树的中序遍历
    问题背景给定一个二叉树的根节点rootrootroot,返回它的中序遍历。数据约......