当前位置: 首页 > news >正文

【算法学习】DFS与BFS

目录

一,深度优先搜索

1,DFS

2,图的DFS遍历

(1),递归实现(隐士栈)

(2),显示栈实现(非递归)

二,广度优先搜索 

1,BFS

2,图的BFS遍历

3,路径记录

小结:

最短路径问题 (BFS)


BFS(广度优先搜索)和DFS(深度优先搜索)

BFS和DFS树是图/树遍历的两种基础算法,核心在于探索顺序和适用场景的不同。

一,深度优先搜索

1,DFS

DFS即Depth First Search,深度优先搜索。遍历顺序为:沿分支深入到底再回溯,优先探索最新发现的节点。简单来说,就是一条路走到黑。比如对下面一颗树的遍历。

从A开始遍历,再到B,有两种情况,意味着这条路还没有走完,接着走到D,之后就没路了。然后我就回溯到B,因为B还有情况没走完,接着再走到E,之后没路了,就回溯到B,发现B的两种情况以及那个走完了,就再回溯到A,然后走到C...... 

简单理解就是:一条路走动黑,直到没路可走了,再回溯回去,尝试其他路径。

2,图的DFS遍历

DFS的实现方式有两种,一种是递归实现,但递归实现有时会产生栈溢出的风险,可改用显示栈实现。

(1),递归实现(隐士栈)

#include <iostream>
#include <vector>
using namespace std;void DFS(vector<vector<int>>& graph, int node, vector<bool>& visited)
{visited[node] = true;cout << node << " ";    //前序遍历for (int neighbors : graph[node]){if (!visited[neighbors])DFS(graph, neighbors, visited);}}int main()
{//邻接表表示(无向图)vector<vector<int>> graph = {{1,2},      //节点0的邻居是1 2{0,3,4},	//节点1的邻居是0 3 4{0,5},		//节点2的邻居是0 5{1},        //节点3的邻居是1{1},        //节点4的邻居是1{2}         //节点5的邻居是2};//记录访问过的节点vector<bool> visited(graph.size(), false);cout << "DFS结果为:";DFS(graph, 0, visited);return 0;
}

(2),显示栈实现(非递归)


#include <iostream>
#include <stack>
#include <vector>
using namespace std;
void DFS_Stack(vector<vector<int>>& graph, int start)
{vector<bool> visited(graph.size(), false);stack<int> s;s.push(start);visited[start] = true;while (!s.empty()){int node = s.top();s.pop();cout << node << " ";//逆序入栈 以保证和递归顺序一致for (auto it = graph[node].rbegin(); it != graph[node].rend(); it++){int neighbors = *it;if (!visited[neighbors]){visited[neighbors] = true;s.push(neighbors);}}}
}
int main()
{//邻接表表示(无向图)vector<vector<int>> graph = {{1,2},      //节点0的邻居是1 2{0,3,4},	//节点1的邻居是0 3 4{0,5},		//节点2的邻居是0 5{1},        //节点3的邻居是1{1},        //节点4的邻居是1{2}         //节点5的邻居是2};cout << "栈实现遍历结果为:" << endl;DFS_Stack(graph, 0);return 0;
}

二,广度优先搜索 

1,BFS

BFS即Breadth First Search,即广度优先搜索。DFS是一条路走到黑,那么 BFS就可以理解成是在每个岔路口都向前走一步。也可以理解成是一层一层遍历。

从A开始遍历,有两种情况B,C。 将B,C遍历完后,再遍历D,E,F。一层一层的遍历。

上述是对树的BFS,然而树也是一种 图。 不难发现,我们每次搜索的位置都是离当前节点最近的点。因此,BFS是具有最短路性质的。这里用到的贪心策略是:想要找到最短路径,保证每次在选节点时,也就是每次前进的时候,都是距离上一个节点最近的点。

因此,BFS也可以求解最短路问题。

2,图的BFS遍历

#include <iostream>
#include <vector>
#include <queue>
#include <unordered_set>using namespace std;// BFS 遍历函数
void BFS(const vector<vector<int>>& graph, int start) {vector<bool> visited(graph.size(), false); // 访问标记数组queue<int> q;q.push(start);visited[start] = true;while (!q.empty()) {int node = q.front();q.pop();cout << node << " "; // 输出当前节点(可替换为自定义操作)// 遍历所有邻接节点for (int neighbor : graph[node]) {if (!visited[neighbor]) {visited[neighbor] = true;q.push(neighbor);}}}
}int main() {// 示例图的邻接表表示(无向图)vector<vector<int>> graph = {{1, 2},     // 节点0的邻居是1和2{0, 3, 4},  // 节点1的邻居是0、3、4{0, 5},     // 节点2的邻居是0、5{1},        // 节点3的邻居是1{1},        // 节点4的邻居是1{2}         // 节点5的邻居是2};cout << "BFS遍历结果:";BFS(graph, 0); // 从节点0开始遍历// 输出:0 1 2 3 4 5 return 0;
}

3,路径记录

在图中寻找一条从开始到目标target的路径。

vector<int> BFS_Path(vector<vector<int>>& graph, int start, int target)
{vector<bool> visited(graph.size(), false);  //记录访问过的节点vector<int> parent(graph.size(), -1);  //记录父节点queue<int> q;q.push(start);visited[start] = true;while (!q.empty()){int node = q.front();q.pop();if (node == target)break;for (int neighbors : graph[node]){if (!visited[neighbors]){visited[neighbors] = true;parent[neighbors] = node; //neighbors的父节点nodeq.push(neighbors);}}}vector<int> path;for (int at = target; at != -1; at = parent[at])path.push_back(at);reverse(path.begin(), path.end());return path;
}

最短路径问题 (BFS)

【题目描述】

给的那个一个n*m的二维整数数组,用来表示迷宫,数组中只包含1和0,0表示可以走的路,1表示不可以通过的墙壁。

最初,有一个人位于左上角(1,1)处,已知改人每次可以向上,下,做,右任意一个方向移动一个位置。请问:改人从左上角移动到右下角(n,m),至少需要移动多少次。数据保证(0,0)和(n,m)的位置均为0。且一定至少存在一条通路。

【输入格式】

第一行包含两个整数n和m。

接下来n行,每行包含m个整数(0或1),表示迷宫。

【输出格式】

表示最少移动次数。

本题求的是最短路,所以可以用bfs从当前节点出发,每次向四周扩展。

#include <iostream>
#include <queue>
#include <cstring>
using namespace std;typedef pair<int, int> PII;//方向数组
int dx[4] = { -1,0,1,0 }, dy[4] = { 0,1,0,-1 };
const int N = 110;
int map[N][N];  //迷宫
int mark[N][N];  //标记数组
int n, m;void BFS()
{memset(mark, -1, sizeof(mark));queue<PII> q;q.push({ 0,0 });mark[0][0] = 0;while (!q.empty()){PII top = q.front();q.pop();for (int i = 0; i < 4; i++){int x = top.first + dx[i];int y = top.second + dy[i];if (x >= 0 && x < n && y >= 0 && y < m && mark[x][y] == -1 && map[x][y] == 0){q.push({ x,y });mark[x][y] = mark[top.first][top.second] + 1;}}}cout<<mark[n - 1][m - 1]<<endl;
}
int main()
{cin >> n >> m;for (int i = 0; i < n; i++)for (int j = 0; j < m; j++)cin >> map[i][j];BFS();return 0;
}

小结:

BFS优势与局限
  • 优点

    • 保证找到最短路径(无权图)。

    • 避免深度过大的栈溢出风险。

  • 缺点

    • 空间消耗大(存储整层节点)。

    • 不适合目标节点在深层的情况(效率低)。

DFS优势与局限
  • 优点

    • 空间效率高(仅存储当前路径)。

    • 适合寻找所有解(如回溯算法)。

  • 缺点

    • 可能陷入无限深的分支(需设置最大深度)。

    • 递归实现有栈溢出风险(可改用显式栈)。

相关文章:

【算法学习】DFS与BFS

目录 一&#xff0c;深度优先搜索 1&#xff0c;DFS 2&#xff0c;图的DFS遍历 (1)&#xff0c;递归实现&#xff08;隐士栈&#xff09; (2)&#xff0c;显示栈实现&#xff08;非递归&#xff09; 二&#xff0c;广度优先搜索 1&#xff0c;BFS 2&#xff0c;图的BF…...

100.16 AI量化面试题:监督学习技术在量化金融中的应用方案

目录 0. 承前1. 解题思路1.1 应用场景维度1.2 技术实现维度1.3 实践应用维度 2. 市场预测模型2.1 趋势预测2.2 模型训练与评估 3. 风险评估模型3.1 信用风险评估 4. 投资组合优化4.1 资产配置模型 5. 回答话术 0. 承前 本文通过通俗易懂的方式介绍监督学习在量化金融中的应用&a…...

基于deepseek api和openweather 天气API实现Function Calling技术讲解

以下是一个结合DeepSeek API和OpenWeather API的完整Function Calling示例&#xff0c;包含意图识别、API调用和结果整合&#xff1a; import requests import json import os# 配置API密钥&#xff08;从环境变量获取&#xff09; DEEPSEEK_API_KEY os.getenv("DEEPSEE…...

线性数据结构解密:数组的定义、操作与实际应用

系列文章目录 01-从零开始掌握Python数据结构&#xff1a;提升代码效率的必备技能&#xff01; 02-算法复杂度全解析&#xff1a;时间与空间复杂度优化秘籍 03-线性数据结构解密&#xff1a;数组的定义、操作与实际应用 文章目录 系列文章目录前言一、数组的定义与特点1.1 数组…...

CentOS搭建PPPOE服务器

一、安装软件包 yum -y install rp-pppoe 二、配置服务器 1.修改配置文件 打开/etc/ppp/pppoe-server-options文件 nano /etc/ppp/pppoe-server-options 编辑为以下内容&#xff1a; # PPP options for the PPPoE server # LIC: GPL require-pap require-chap login …...

【报错】解决 RuntimeError: CUDA error: CUBLAS_STATUS_INVALID_VALUE 报错问题

解决 RuntimeError: CUDA error: CUBLAS_STATUS_INVALID_VALUE 报错问题 写在最前面问题描述可能的原因分析解决方案该命令的作用 结论 写在最前面 在多用户使用的服务器上&#xff0c;导致的环境变量的冲突和不匹配问题&#xff0c; 代码没有问题&#xff0c;但程序运行异常。…...

【C语言】C语言 文具店商品库存管理系统(源码+数据文件)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;专__注&#x1f448;&#xff1a;专注主流机器人、人工智能等相关领域的开发、测试技术。 系列文章目录 目录 系列文章目录一、设计要求1. 项…...

LangChain系列: 使用工具和工具包构建代理实战教程

让我们在LangChain中构建简单代理示例&#xff0c;以帮助我们理解代理的基本概念和构建块。通过保持简单&#xff0c;我们可以更好地掌握这些代理背后的基本思想&#xff0c;使我们能够在未来构建更复杂的代理。 什么是代理 LangChain官方文档有非常好的章节来介绍其代理的高级…...

布隆过滤器(简单介绍)

布隆过滤器&#xff08;Bloom Filter&#xff09; 是一种高效的概率型数据结构&#xff0c;用于快速判断一个元素是否可能存在于某个集合中。它的核心特点是空间效率极高&#xff0c;但存在一定的误判率&#xff08;可能误报存在&#xff0c;但不会漏报&#xff09;。 核心原理…...

C++ 利器:inline 与 nullptr

探秘 C 利器&#xff1a;inline 与 nullptr 引言 在 C 的浩瀚海洋中&#xff0c;有着许多实用且强大的特性&#xff0c;它们如同夜空中闪烁的繁星&#xff0c;照亮了开发者前行的道路。今天&#xff0c;我们要深入探索其中两颗耀眼的星星&#xff1a;inline 关键字和 nullptr …...

给一个单体项目加装Feign

1.导入pom坐标 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>4.1.2</version> </dependency> 2.主函数注解 EnableFeignClients public cl…...

可以使用Deepseek R1模型的平台集锦

最近Deepseek掀起了AI浪潮&#xff0c;就在今天百度文心一言和ChatGPT宣布要在近期实施免费开放&#xff0c;日渐减少的用户。Deepseek这么火爆&#xff0c;其官网却一直遭受攻击&#xff0c;访问速度很慢。自己本地部署&#xff0c;又负担不起硬件费用&#xff0c;相比之下&am…...

“探索1688平台:高效获取店铺商品信息的实用指南“

在电商领域&#xff0c;获取店铺所有商品信息对于商家进行数据分析、库存管理、竞品分析等方面具有重要意义。1688平台作为中国领先的B2B电商平台&#xff0c;提供了丰富的API接口供开发者使用&#xff0c;其中就包括获取店铺所有商品信息的接口。本文将详细介绍如何使用该接口…...

在fedora41中安装钉钉dingtalk_7.6.25.4122001_amd64

在Fedora-Workstation-Live-x86_64-41-1.4中安装钉钉dingtalk_7.6.25.4122001_amd64.deb 到官网下载钉钉Linux客户端com.alibabainc.dingtalk_7.6.25.4122001_amd64.deb https://page.dingtalk.com/wow/z/dingtalk/simple/ddhomedownload#/ 一、直接使用dpkg命令安装deb包报错…...

数据结构:图论入门

图论起源于欧拉对哥尼斯堡七桥问题的解决. 他构建的图模型将陆地用点来表示, 桥梁则用线表示, 如此一来, 该问题便转化为在图中能否不重复地遍历每条边的问题. 图论的应用 地图着色 在地图着色问题中, 我们用顶点代表国家, 将相邻国家之间用边相连. 这样, 问题就转化为用最少…...

有限状态系统的抽象定义及CEGAR分析解析理论篇

文章目录 一、有限状态系统的抽象定义及相关阐述1、有限状态系统定义2、 有限状态系统间的抽象关系&#xff08;Abstract&#xff09;2.1 基于函数的抽象定义2.2 基于等价关系的抽象定义 二、 基于上面的定义出发&#xff0c;提出的思考1. 为什么我们想要/需要进行抽象2. 抽象是…...

Apache Hive用PySpark统计指定表中各字段的空值、空字符串或零值比例

from pyspark.sql import SparkSession from pyspark.sql.functions import col, coalesce, trim, when, lit, sum from pyspark.sql.types import StringType, NumericType# 初始化SparkSession spark SparkSession.builder \.appName("Hive Data Quality Analysis"…...

高校元宇宙实训室解决方案:以技术驱动教育,用数字人链接未来

在AIGC技术的浪潮下&#xff0c;AI数字人正成为数字营销、文化传播等领域的核心工具。为助力高校培养适应未来需求的新型人才&#xff0c;广州虚拟动力推出高校元宇宙实训室解决方案&#xff0c;通过动作捕捉设备与虚拟数字人技术&#xff0c;构建沉浸式教学场景&#xff0c;赋…...

提升编程效率,体验智能编程助手—豆包MarsCode一键Apply功能测评

提升编程效率&#xff0c;体验智能编程助手—豆包MarsCode一键Apply功能测评 &#x1f31f; 嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 目录 引言豆包…...

【前端开发】query参数和params参数的区别

在Web开发中&#xff0c;query参数&#xff08;URL查询参数&#xff09;和params参数&#xff08;路由参数&#xff09;是两种不同的URL传参方式&#xff0c;它们的核心区别如下&#xff1a; 一、 位置不同 query参数params参数位置URL中?之后&#xff0c;用&连接多个参数…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

跨链模式:多链互操作架构与性能扩展方案

跨链模式&#xff1a;多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈&#xff1a;模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展&#xff08;H2Cross架构&#xff09;&#xff1a; 适配层&#xf…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...