C++:图的遍历

news2024/11/27 6:12:27

一、简介

        图的遍历通常有深度优先遍历广度优先遍历两种方式,这两种遍历次序对无向图和有向图都使用。

         本文分别介绍基于邻接矩阵邻接表的图的深度优先遍历和广度优先遍历,对于邻接矩阵和邻接表不熟悉的可翻阅:C++:图的存储结构及实现

        DFS和BFS的比较:

 二、深度优先遍历

深度优先遍历也叫深度优先搜索(DFS),类似于树的前序遍历。DFS的基本思想是:

  1. 从某个顶点v开始,访问v。
  2. 从v的未被访问的邻接点中选取一个顶点w,然后从w出发进行DFS。
  3. 重复上述两步,直至图中所有和v有路径相通的顶点都被访问到。

图的DFS的应用

  1. 寻找路径:DFS常被用于寻找图中是否存在一条从起点到终点的路径。这适用于无权图的路径搜索,或需要找到所有路径的场景。
  2. 检测连通分量:DFS可以用于在无向图中检测图中的连通分量,即通过 DFS 可以找到所有与某一节点连通的节点。
  3. 拓扑排序:对于有向无环图,DFS 可以用于拓扑排序,这在任务调度和依赖关系排序问题中非常有用。
  4. 检测图中的环:在有向图中,DFS 可以用来检测是否存在环。通过检测 DFS 的回边,可以判断是否存在环。

 基于邻接矩阵的图的DFS:

/*已知图的顶点数vertexNum、一维顶点数组vertex、二维邻接矩阵edge*/
void DFS(int v)
{
	vector<bool> visited(vertexNum,false);  //存储访问状态
	visited[v] = true;                      //标记该点为已访问
	cout << vertex[v];                      //对访问到的点执行相应操作
	for (int i = 0; i < vertexNum; i++)     //遍历每个顶点
	{
		if (edge[v][i] == 1 && !visited[i]) //v到该顶点有通路且该顶点未被访问
		{
			DFS(i);                         //从该点开始继续深度优先遍历
		}
	}
}

 基于邻接表的图的DFS:

/*已知图的顶点数vertexNum、邻接表的相关信息*/
void DFS(int v)
{
	vector<bool> visited(vertexNum, false);
	int j;
	EdgeNode* p = nullptr;          //p作为工作指针
	visited[v] = true;              //标记该点已被访问
	cout << adjlist[v].vertex;      //对该点执行相关操作
	p = adjlist[v].firstEdge;       //p指向顶点v的边表
	while (p != nullptr)
	{
		j = p->adjvex;
		if (!visited[j])
		{
			DFS(j);
		}
		p = p->next;
	}
}

 三、广度优先遍历

        广度优先遍历也叫广度(宽度)优先搜索(BFS),类似于树的层序遍历。BFS的基本思想是:

  1. 从某个顶点v开始,访问v。
  2. 依次访问v的各个未被访问的邻接点v1、v2、... 、vk。
  3. 分别从v1、v2、... 、vk出发依次访问它们未被访问的邻接点,直至图中所有与顶点v有路径相通的顶点都被访问到。

         图的BFS的应用

  1. 最短路径搜索:BFS可以用来在无权图中找到从起点到终点的最短路径。这是因为它逐层扩展,保证了在找到目标节点时,路径是最短的。
  2. 搜索引擎中的网页爬虫:搜索引擎的爬虫通常使用 BFS 来遍历网络。BFS 可以确保爬虫首先抓取到距离当前网页“最近”的网页,从而逐步扩展覆盖整个互联网。
  3. 分层搜索:BFS 的逐层搜索特性可以帮助找到某个层次的所有节点。这种分层搜索在许多现实问题中非常实用,尤其是当我们需要逐层分析某些结构时。
  4. 最小生成树:在无向图中,BFS 也是构建最小生成树的一种常见方式。尽管常用 Prim 或 Kruskal 算法,但 BFS 仍然可以帮助找到无权图中的最小生成树。

 基于邻接矩阵的图的BFS:

/*已知图的顶点数vertexNum、一维顶点数组、二维邻接矩阵*/
void BFS(int v)
{
	vector<bool> visited(vertexNum, false);//存储访问状态
	int w, j, vector<int> que(vertexNum);  //采用顺序队列
	int front = -1, rear = -1;             //初始化队列
	
	visited[v] = true;                     //标记该点为已访问
	cout << adjlist[v].vertex;             //执行与该点相关的操作

	que[++rear] = v;                       //被访问的顶点入队
	while (front != rear)                  //当队列非空
	{
		w = que[++front];                  //取队头元素
		
		for (j = 0; j < vertexNum; j++)    //遍历每个节点
		{
			if (edge[w][j] == 1 && !visited[j])//若该节点与w节点有通路且未被访问
			{
				visited[j] = true;         //标记该节点未已访问
				cout << vertex[j];         //执行与该节点相关操作
				que[++rear] = j;           //将该节点入队
			}
		}
	}
}

 基于邻接表的图的BFS:

/*已知图的顶点数vertexNum、邻接表的相关信息*/
void BFS(int v)
{
	vector<bool> visited(vertexNum, false);//存储访问状态
	int w, j, vector<int> que(vertexNum);  //采用顺序队列
	int front = -1, rear = -1;             //初始化队列
	EdgeNode* p = nullptr;                 //工作指针
	visited[v] = true;                     //标记该点为已访问
	cout << adjlist[v].vertex;             //执行与该点相关的操作

	que[++rear] = v;                       //被访问的顶点入队
	while (front != rear)                  //当队列非空
	{
		w = que[++front];
		p = adjlist[w].firstEdge;          //工作指针指向顶点v的边表
		while (p != nullptr)               //当该顶点的邻接点还未访问完
		{
			j = p->adjvex;
			if (!visited[j])               //若该点未被访问
			{
				visited[j] = true;         //标记该点为已访问
				cout << adjlist[j].vertex; //执行与该点相关的操作
				que[++rear] = j;           //队列元素-1
			}
			p = p->next;                   //工作指针指向下一个邻接点
		}
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

dockerpull

20241006更新&#xff0c;亲测可用。 注意&#xff1a;这个方法随时可能会失效。 编辑配置文件&#xff0c;修改镜像源&#xff1a; vi /etc/docker/daemon.json {"registry-mirrors": ["https://do.nark.eu.org","https://dc.j8.work","…

TypeScript 第三部分 扩展

1. 声明文件 主要作用&#xff1a; 类型声明&#xff1a;为库或模块提供类型信息。全局声明&#xff1a;为全局作用域中的类型和变量提供声明。类型兼容性&#xff1a;确保第三方库或自定义代码的类型正确性。代码提示与检查&#xff1a;在开发环境中提供更好的代码提示和类型…

Sollong手机——一站式Web3生态解决方案

从定义上讲&#xff0c;Web3公司也属于互联网公司&#xff0c;不过与传统互联网公司相比&#xff0c;他们有一个很明显的特征&#xff1a;他们不断尝试做去中心化的事&#xff0c;一步步将数据和金融的控制权从美联储&#xff08;央行和金融机构&#xff09;、苹果&#xff08;…

2024/10/6周报

文章目录 摘要Abstract广西的一些污水处理厂工艺解析1. A/O工艺&#xff08;厌氧-缺氧-好氧工艺&#xff09;2. 氧化沟工艺3. MBR工艺&#xff08;膜生物反应器&#xff09;4. SBR工艺&#xff08;序批式活性污泥法&#xff09;5. 生物接触氧化法 其它补充一体化改良氧化沟工艺…

Linux的基础指令(下)

压缩包 这里不为打包和压缩做仔细的区分&#xff1b; 打包&#xff1a; 文件合并&#xff1b; 主要目的是在文件传输&#xff0c;移动时&#xff0c;能有效减少文件的缺失&#xff1b; 压缩&#xff1a;为了减小文件体积&#xff0c;内存&#xff1b; 主要目的是减小使用体…

在JS中定义和使用Vector2

概述 Vector2是GDSCript中表示二维向量的类型&#xff0c;你会发现无论在任何编程语言中&#xff0c;只要你想很好的实现2D绘图以及几何和物理相关&#xff0c;Vector2是你必须要实现的一个类。我之前学C时就写过一个C的版本。 本篇就介绍我自己在JavaScript中定义的Vector2类…

基于ssm 框架的java 开发语言的 在线教育学习平台系统设计与实现 源码 论文

博主介绍&#xff1a;专注于Java&#xff08;springboot ssm springcloud等开发框架&#xff09; vue .net php phython node.js uniapp小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆…

AI周报(9.29-10.5)

AI应用-Elayne公司临终规划和自动化遗产结算 创业公司Elayne成立于2023年&#xff0c;由Adria Ferrier和Jake Grafenstein共同创立&#xff0c;Adria Ferrier担任CEO&#xff0c;总部位于科罗拉多州丹佛市。 Elayne公司专注于遗产规划和结算领域&#xff0c;通过人工智能技术…

实验4 循环结构

1、判断素数 【问题描述】从键盘输入一个大于1的正整数&#xff0c;判断是否为素数 【输入形式】输入一个正整数 【输出形式】输出该数是否为素数 【样例输入】10 【样例输出】10 is not a prime number 【样例说明】样例2 输入&#xff1a;-10 输出&#xff1a;error! #de…

实景三维赋能矿山安全风险监测预警

随着科技的不断进步&#xff0c;实景三维技术在矿山安全风险监测预警中的应用越来越广泛&#xff0c;它为矿山安全管理带来了革命性的变革。 一、矿山安全现状 矿山作为国家重要的能源和原材料基地&#xff0c;其安全生产直接关系到国民经济的发展和社会的稳定。然而&#xf…

【前端vue2 + element ui】Dialog 对话框:.vue组件跳转

【前端vue2 element ui】Dialog 对话框&#xff1a;.vue组件跳转 写在最前面一、父组件调用1、<template>1.1 跳转位置1.2 弹窗调用 2、<script>2.1 import2.2 export2.3 methods 二、子组件调用1、<template>2、<script>2.1 export2.2 watch和method…

不可错过!CMU最新《生成式人工智能大模型》课程:从文本、图像到多模态大模型

1. 课程简介 从生成图像和文本到生成音乐和艺术&#xff0c;生成模型一直是人工智能的关键挑战之一。本课程将探讨推动生成模型和基础模型&#xff08;Foundation Models&#xff09;最近进展的机器学习和人工智能技术。学生将学习、开发并应用最先进的算法&#xff0c;使机器…

windows下,在vscode中使用cuda进行c++编程

安装cuda CUDA Toolkit Downloads | NVIDIA Developer 这里网上教程多的是&#xff0c;在这个网址下载安装即可 我这台电脑因为重装过&#xff0c;所以省去了安装步骤&#xff0c;但是要重新配置环境变量。我重新找到了重装之前的CUDA位置(关注这个bin文件夹所在的目录) 在…

Canvas指纹:它是什么以及如何避免被Canvas指纹识别跟踪

Canvas指纹识别技术已成为追踪在线行为的一种隐蔽手段。尽管这个技术在某些方面有其正当用途&#xff0c;它也可能被用于监视我们的在线活动&#xff0c;不经我们的同意就收集个人信息。 你认为启用Canvas指纹禁用功能就能使你在网络上无迹可寻吗&#xff1f;可能需要重新考虑…

开放式耳机是什么意思?漏音吗?开放式的运动蓝牙耳机推荐

目前运动耳机市场主要分为入耳式、骨传导和开放式三类。入耳式耳机占比30%-40%&#xff0c;虽目前占比较大&#xff0c;但因在运动场景下有闷塞感、出汗不适、屏蔽外界环境音带来安全隐患等缺点&#xff0c;占比会逐渐下降。 骨传导耳机占比也为30%-40%&#xff0c;其不堵塞耳…

macos 中使用macport安装,配置,切换多版本php,使用port 安装php扩展方法总结

macport是一款mac系统中比较优秀的软件包管理工具&#xff0c;他与brew的最大区别在于软件包的安装速度相当的快&#xff0c;以安装php为例&#xff0c; 使用port安装和使用brew安装&#xff0c;port方式安装要比brew方式安装要快最少10倍以上&#xff0c; 因为port安装软件包时…

javaScript数组(16个案例+代码+效果图)

目录 1.数组的概念 2.创建数组 1.通过数组字面量创建数组 1.代码 2.效果 2.通过new Array()创建数组 1.代码 2.效果 3.数组的基本操作 1.获取数组的长度 案例:获取数组的长度 1.代码 2.效果 2.修改数组的长度 1.代码 2.效果 4.访问数组 案例:访问数组 1.代码 2.效果 5.遍历数组…

实验3 选择结构

1、计算分段函数的值 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <math.h> int main() {double x,y0;scanf("%lf",&x);if(x<0){printf("error!\n");return 0;}if(0<x&&x<1){ylog10(x);}else if(1<…

第十四周:机器学习

目录 摘要 Abstract 一、生成式对抗网络&#xff08;下&#xff09; 1、回顾 2、生成式模型 3、generative评价指标 4、conditional generation 5、cycle GAN 二、总结 摘要 接着上周对GAN的初步概念了解及其理论推导&#xff0c;本周回顾了GAN难以训练的问题&#…

常见排序详解(历时四天,哭了,必须释放一下)

目录 1、插入排序 1.1 基本思想 1.2 直接插入排序 1.2.1 思路 1.2.2 代码实现 1.2.3 性质 1.3 希尔排序 1.3.1 思路 1.3.2 代码实践 1.3.3 性质 2、选择排序 2.1 基本思想 2.2 直接选择排序 2.2.1 思路 2.2.2 代码实践 2.2.3 性质 2.3 堆排序 2.3.1 思路 2.…