图的遍历-DFS,BFS(代码详解)

2023-10-28

前言

        大家好,今天给大家带来的是图遍历的算法,DFS(深度优先遍历),BFS(广度优先遍历)。这两个算法是比较重要和常用的算法,但是在图中的实现只是最基本的操作,要是想完全掌握,还是需要去多练题。对应相关题目链接点击这里刷算法相关题目

目录

前言

图的定义

图的相关术语

 图的创建(邻接矩阵)---结构体

  图的创建(邻接矩阵)---邻接矩阵的创建

图的创建(邻接表)---结构体

 图的创建(邻接表)---邻接表的创建

 对邻接矩阵进行深度优先遍历

  对邻接矩阵进行广度优先遍历

对邻接表进行深度优先遍历 

 对邻接表进行广度优先遍历 

整体代码

结果展示

结束语

图的定义

        图由顶点集V(G)边集E(G)组成,记为G=(V,E)。其中E(G)是边的有限集合,边是顶点的无序对(无向图)或有序对(有向图)。对于有向图来说,E(G)是有向边(也称弧(Arc))的有限集合,弧是顶点的有序对,记为<v,w>,v、w是顶点,v为弧尾(箭头根部),w为弧头(箭头处)。对于无向图来说,E(G)是边的有限集合,边是顶点的无序对,记为(v, w)或者(w, v),并且(v, w)=(w,v)。

图的相关术语

①顶点(Vertex):图中的数据元素。

②顶点v的度:与v相关联的边的数目;

③顶点v的出度:以v为起点有向边数;

④顶点v的入度:以v为终点有向边数。

⑤边:顶点之间的逻辑关系用边来表示,边集可以是空的。

⑥无向边(Edge):若顶点V1到V2之间的边没有方向,则称这条边为无向边。

⑦无向图(Undirected graphs):图中任意两个顶点之间的边都是无向边。(A,D)=(D,A)

⑧有向边:若从顶点V1到V2的边有方向,则称这条边为有向边,也称弧(Arc)。用<V1,V2>表示,V1为狐尾(Tail),V2为弧头(Head)。(V1,V2)≠(V2,V1)。

⑨有向图(Directed graphs):图中任意两个顶点之间的边都是有向边。

                              注意:无向边用“()”,而有向边用“< >”表示。

⑩简单图:图中不存在顶点到其自身的边,且同一条边不重复出现。

⑪无向完全图:无向图中,任意两个顶点之间都存在边。

⑫有向完全图:有向图中,任意两个顶点之间都存在方向互为相反的两条弧。

⑬稀疏图:有很少条边。

⑭稠密图:有很多条边。

⑮权(Weight):与图的边或弧相关的数。

⑯网(Network):带权的图。

⑰连通图:图中任意两个顶点都是连通的。

⑱极大连通子图:该子图是G连通子图,将G的任何不在该子图的顶点加入,子图将不再连通。

⑲极小连通子图:该子图是G的连通子图,在该子图中删除任何一条边,子图都将不再连通。

 图的创建(邻接矩阵)---结构体

typedef struct
{
	//用来存放顶点
	int vexs[MAX];
	//二维数组:用来存放两点之间的关系
	int arcs[MAX][MAX];
	//图的顶点数和边数
	int vexsum, arcsnum;
}AMGraph,*StrAMGraph;

  图的创建(邻接矩阵)---邻接矩阵的创建

int locate(AMGraph&G, int n)
{
	for (int i = 0; i < G.vexsum; i++)
	{
		if (G.vexs[i] == n)
		{
			return i;
		}
	}
}

//创建邻接矩阵
void Creat(AMGraph&G)
{
	int v1 = 0, v2 = 0, w = 0;
	cin >> G.vexsum >> G.arcsnum;
	for (int i = 0; i < G.vexsum; i++)
	{
		cin >> G.vexs[i];
	}
	for (int i = 0; i < G.vexsum; i++)
	{
		for (int j = 0; j < G.vexsum; j++)
		{
			G.arcs[i][j] = 0;
		}
	}
	for (int k = 0; k < G.arcsnum; k++)
	{
		cin >> v1 >> v2 >> w;
		int i = locate(G, v1);
		int j = locate(G, v2);
		G.arcs[i][j] = w;
	}
}

图的创建(邻接表)---结构体

typedef struct ArcNode
{
	int Adjust;
	struct ArcNode *next;
}AcrNode,*StrAcrNode;


typedef struct
{
	int data;
	StrAcrNode next;
}HeadNode, *StrHeadNode;


typedef struct 
{
	HeadNode arr[MAX];
	int acsrnum, vexsnum;
}ALGraph, *StrALGraph;

 图的创建(邻接表)---邻接表的创建

int locate1(ALGraph&G, int n)
{
	for (int i = 0; i < G.vexsnum; i++)
	{
		if (G.arr[i].data == n)
		{
			return i;
		}
	}
}

void CreatALGraph(ALGraph&G)
{
	int v1 = 0, v2 = 0, w = 0;
	cin >> G.vexsnum >> G.acsrnum;
	for (int i = 0; i < G.vexsnum; i++)
	{
		cin >> G.arr[i].data;
		G.arr[i].next = NULL;
	}
	for (int k = 0; k < G.acsrnum; k++)
	{
		cin >> v1 >> v2;
		int i = locate1(G, v1);
		int j = locate1(G, v2);
		StrAcrNode p1;
		p1 = new AcrNode;
		p1->next = G.arr[i].next;
	}
}

 对邻接矩阵进行深度优先遍历

//对邻接矩阵进行深度优先遍历
void DFS(AMGraph&G, int n)
{
	cout << G.vexs[n] << " ";
	visit[n] = 1;
	for (int i = 0; i < G.vexsum; i++)
	{
		if (G.arcs[n][i] != 1 && visit[i] != 1)
		{
			DFS(G, G.arcs[n][i]);
		}
	}
}

  对邻接矩阵进行广度优先遍历

queue<int> qu;
//对邻接矩阵进行广度优先遍历
void BFS(AMGraph&G, int n)
{
	cout << G.vexs[n] << " ";
	qu.push(n);
	while (!qu.empty())
	{
		int m = qu.front();
		qu.pop();
		for (int i = 0; i < G.vexsum; i++)
		{
			if (visit[i] != 1 && G.arcs[m][i] != 1)
			{
				cout << G.vexs[i] << " ";
				visit[i] = 1;
				qu.push(i);
			}
		}
	}
}

对邻接表进行深度优先遍历 

void DFS1(ALGraph&G, int n)
{
	cout << G.arr[n].data << " ";
	visit3[n] = 1;
	StrAcrNode p1;
	p1 = G.arr[n].next;
	while (p1)
	{
		int w = p1->Adjust;
		if (visit3[w] != 1)
		{
			DFS1(G, w);
		}
		p1 = p1->next;
	}
}

queue<int> qu1;

 对邻接表进行广度优先遍历 

queue<int> qu1;
void BFS(ALGraph&G, int n)
{
	cout << G.arr[n].data << " ";
	visit4[n] = 1;
	qu1.push(n);
	StrAcrNode p1;
	p1 = G.arr[n].next;
	while (!qu1.empty())
	{
		qu1.pop();
		int w = p1->Adjust;
		while (p1)
		{
			if (visit4[w] != 1)
			{
				qu1.push(w);
				visit4[w] = 1;
			}
			p1 = p1->next;
		}
	}
}

整体代码

#include<iostream>
#include<queue>
using namespace std;
const int MAxInt = 10;
int visit[MAxInt];

typedef struct
{
	int vexs[MAxInt];
	int arcs[MAxInt][MAxInt];
	int arcnum, vexsnum;
}AMGraph;

int locate(AMGraph&G, int n)
{
	for (int i = 0; i < G.vexsnum; i++)
	{
		if (G.vexs[i] == n)
		{
			return i;
		}
	}
}

void Creat(AMGraph&G)
{
	int v1 = 0, v2 = 0, w = 0;
	cin >> G.vexsnum >> G.arcnum;
	for (int i = 0; i < G.vexsnum; i++)
	{
		cin >> G.vexs[i];
	}
	for (int i = 0; i < G.vexsnum; i++)
	{
		for (int j = 0; j < G.vexsnum; j++)
		{
			G.arcs[i][j] = MAxInt;
		}
	}
	for (int k = 0; k < G.arcnum; k++)
	{
		cin >> v1 >> v2 >> w;
		int i = locate(G, v1);
		int j = locate(G, v2);
		G.arcs[i][j] = w;
		G.arcs[j][i] = w;
	}
}



queue<int> qu;
void BFS(AMGraph G, int v)
{
	cout << G.vexs[v];
	qu.push(v);
	visit[v] = 1;
	while (!qu.empty())
	{
		int w = qu.front();
		qu.pop();
		for (int i = 0; i < G.vexsnum; i++)
		{
			if (visit[i] != 1 && G.arcs[w][i] != MAxInt)
			{
				cout << G.vexs[i] << " ";
				visit[i] = 1;
				qu.push(i);
			}
		}
	}
}

int main()
{
	AMGraph G;
	Creat(G);
	cout << "对图进行广度优先遍历的结果为" << endl;
	BFS(G, 1);
	return 0;
}

注意 :这里的代码是创建一个邻接矩阵来对图进行广度优先遍历,对图进行深度优先遍历以及临界表实现对图进行广度优先遍历,对图进行深度优先遍历大家都可以通过上面的代码块进行自由组合实现,这里就不进行一一实现。

结果展示

结束语

        到了这里今天的内容就全部结束了,希望能够给大家带来帮助,最后大家可以进入该链接进行练习DFS和BFS相关的题目点击这里刷算法相关题目 

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

图的遍历-DFS,BFS(代码详解) 的相关文章

随机推荐

  • 使用shell脚本更新文本数据至mysql数据库

    1 getgamedesc sh 功能 插入gamedesc txt文本中的 以 分割的第1列数据gid和第6列数据desc 到线网mysql数据库中 当字段 desc不为空时才执行插入 db param h127 0 0 1 uuser
  • qml文件之间的交互

    一 调用js函数 1 定义对方qml的id号 对方文件名要大写 2 KeyBoard qml定义js函数 3 自己的qml文件中进行调用 二 通过自定义属性的方式 1 本例使用子qml调用父qml 2 父id号 root 3 父qml文件中
  • 运维之道

    Docker 镜像使用 当运行容器时 使用的镜像如果在本地中不存在 docker 就会自动从 docker 镜像仓库中下载 默认是从 Docker Hub 公共镜像源下载 下面我们来学习 管理和使用本地 Docker 主机镜像 创建镜像 一
  • 高并发优化实战-连接数满载

    1 第三方http请求处理 finally httpclient getConnectionManager shutdown 2 linux服务器tcp处理 端口释放后的等待时间 默认为60s sysctl w net ipv4 tcp f
  • Vue2和Vue3的生命周期以及执行顺序

    前言 vue3现在是比较流行的 但是vue2的项目现在很多 而且我们会遇到把一部分vue2的项目移植到我们的vue3项目里面的情况 在这种情况下 如果我们熟悉vue2与vue3的生命周期顺序的话 对我们帮助是很大的 vue3生命周期的方法
  • php对接苹果cms采集接口,苹果cms的资讯采集api接口以及使用教程

    好多朋友都在说 想建个电影网站 电影资源大家都知道去某某影视资源网去找接口 蛋是这些资源网只有视频流媒体的网址 采集到的也是播放用的数据 那么苹果cms的资讯 以及演员是在哪里采集呢 那么请往下看 首先苹果cms的采集接口api是这种样子的
  • STP生成树协议与实验详解

    1 生成树协议概述 1 生成树协议简介 为了提高网络可靠性 交换网络中通常会使用冗余链路 然而 冗余链路会给交换网络带来环路风险 并导致广播风暴以及MAC地址表不稳定等问题 进而会影响到用户的通信质量 为了解决交换网络的环路问题 那么需要一
  • leetcode 934. 最短的桥(C++、python)

    在给定的二维二进制数组 A 中 存在两座岛 岛是由四面相连的 1 形成的一个最大组 现在 我们可以将 0 变为 1 以使两座岛连接起来 变成一座岛 返回必须翻转的 0 的最小数目 可以保证答案至少是 1 示例 1 输入 0 1 1 0 输出
  • 记录那些踩过的坑 - NSS error -5938 (PR_END_OF_FILE_ERROR), curl: (35) Encountered end of file

    PHP通过curl POST数据到https 同样的code 在第一个server上没有问题 在第二个server上却一直不成功 于是打开debug mode发现了下面的log code try 1 init curl ch curl in
  • Spring boot自定义切面拦截所有的请求 或者方法原理一样

    原代码 下面的例子是小编在自己的环境中测试过得 代码 Pointcut execution public com controller SysLoginController and execution public com controll
  • 卡内基梅隆大学计算机研究生水平,卡内基梅隆大学计算机研究生

    卡内基梅隆大学计算机研究生学位项目 立思辰留学云介绍 卡耐基梅隆大学计算机科学系 Computer Science Department 开设的研究生学位项目有 计算机科学博士 Ph D in Computer Science 授课地点在匹
  • [论文阅读] (26) 基于Excel可视化分析的论文实验图表绘制总结——以电影市场为例

    娜璋带你读论文 系列主要是督促自己阅读优秀论文及听取学术讲座 并分享给大家 希望您喜欢 由于作者的英文水平和学术能力不高 需要不断提升 所以还请大家批评指正 非常欢迎大家给我留言评论 学术路上期待与您前行 加油 前文详细介绍了向量表征系列文
  • mysql如何连接命令行_如何通过命令行连接mysql

    1 如何通过命令行连接mysql数据库 windows端 需要在命令行中进入mysql所在的目录下 进入bin目录下 比如我的路径是在 e tmallStudy mysql MySQL Server 5 7 bin下输入 mysql hlo
  • 华为OD机试真题- 快速开租建站【2023Q1】【JAVA、Python、C++】

    题目描述 当前IT部门支撑了子公司颗粒化业务 该部门需要实现为子公司快速开租建站的能力 建站是指在一个全新的环境部署一套IT服务 每个站点开站会由一系列部署任务项构成 每个任务项部署完成时间都是固定和相等的 设为1 部署任务项之间可能存在依
  • 机器学习算法——GBDT

    1 简介 GBDT全称梯度下降树 在传统机器学习算法里面是对真实分布拟合的最好的几种算法之一 在前几年深度学习还没有大行其道之前 gbdt在各种竞赛是大放异彩 原因大概有几个 一是效果确实挺不错 二是即可以用于分类也可以用于回归 三是可以筛
  • 【WIFI】WIFI-HT的意思

    HT40 使用40MHz频宽 但只支持1 7信道 HT40 使用40MHz频宽支持5 13信道 HT20 支持1 13信道 20MHz频宽 我们AP的802 11n默认是支持的 不需额外配置 如果radio设为11b 即是802 11ng
  • 五分钟了解JumpServer V3版本升级注意事项与平滑升级

    一 升级前数据梳理 1 账号 因 JumpServer V3 版本剔除了原本的系统用户功能 将资产与账号直接绑定 故升级前需保证每一台资产绑定的系统账号的用户名不重复 即每一个资产只可以保留一个同名账号 不可平滑升级示例 不可平滑升级的原因
  • 小程序的使用

    文件介绍 sitemap json 站点地图 微信搜一搜里面哪些页面可以展示 哪些不能 project config json 项目配置 app js 全局业务逻辑 app json 全局的小程序配置 app wxss 全局的样式 page
  • C++求行列式(满足一般性的解法)

    突发奇想对y总的模板进行如下应用 如有不当 还望斧正 由行列式的定义 不同行不同列的n个元素的乘积 当这个乘积列的下标的逆序对个数为偶数时 该项为正 当这个乘积列的下标的逆序对个数为奇数时 该项为负 那么我们需要写一个函数来求出这些数的逆序
  • 图的遍历-DFS,BFS(代码详解)

    前言 大家好 今天给大家带来的是图遍历的算法 DFS 深度优先遍历 BFS 广度优先遍历 这两个算法是比较重要和常用的算法 但是在图中的实现只是最基本的操作 要是想完全掌握 还是需要去多练题 对应相关题目链接点击这里刷算法相关题目 目录 前