当前位置: 首页 > 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;用&连接多个参数…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...