深入解析BFS算法:C++实现无权图最短路径的高效解决方案
在无权图中,广度优先搜索(BFS)是解决最短路径问题的高效算法。接下来博主从专业角度深入探讨其实现细节,并给出C++代码示例:
目录
一、核心原理
二、算法步骤
三、C++实现关键点
1. 数据结构
2. 边界检查
3. 路径回溯(可选)
四、代码实现
五、路径回溯实现
六、复杂度分析
七、适用场景与限制

一、核心原理
BFS按层遍历节点,确保首次到达目标节点的路径是最短的。其核心特性为:
-
队列管理:先进先出(FIFO)保证按层扩展。
-
访问标记:避免重复访问,防止环路。
-
距离记录:每个节点的距离为父节点距离加1。
二、算法步骤
-
初始化:起点入队,标记距离为0。
-
遍历队列:逐层处理节点,遍历所有合法邻居。
-
终止条件:到达终点时返回距离;队列为空则表示不可达。
三、C++实现关键点
1. 数据结构
-
队列:存储待处理节点,使用
queue<pair<int, int>>。 -
距离矩阵:记录每个节点的最短距离,初始化为-1表示未访问。
-
方向数组:定义移动方向(如4方向或8方向)。
int dx[] = {-1, 1, 0, 0}; // 上下左右
int dy[] = {0, 0, -1, 1};
2. 边界检查
确保新坐标在网格范围内,且节点可访问(非障碍、未访问)。
3. 路径回溯(可选)
通过父节点矩阵记录路径,回溯时从终点反向追踪至起点。
四、代码实现
#include <iostream>
#include <vector>
#include <queue>
using namespace std;int bfsShortestPath(vector<vector<int>>& grid, pair<int, int> start, pair<int, int> end) {int n = grid.size();if (n == 0) return -1;int m = grid[0].size();queue<pair<int, int>> q;vector<vector<int>> dist(n, vector<int>(m, -1));int dx[] = {-1, 1, 0, 0};int dy[] = {0, 0, -1, 1};// 初始化起点q.push(start);dist[start.first][start.second] = 0;while (!q.empty()) {auto curr = q.front();q.pop();// 到达终点if (curr.first == end.first && curr.second == end.second) {return dist[curr.first][curr.second];}// 遍历四个方向for (int i = 0; i < 4; ++i) {int x = curr.first + dx[i];int y = curr.second + dy[i];// 检查新坐标是否合法if (x >= 0 && x < n && y >= 0 && y < m && grid[x][y] == 0 && dist[x][y] == -1) {dist[x][y] = dist[curr.first][curr.second] + 1;q.push({x, y});}}}return -1; // 不可达
}// 示例用法
int main() {vector<vector<int>> grid = {{0, 1, 0, 0},{0, 0, 0, 1},{1, 1, 0, 0},{0, 0, 0, 0}};pair<int, int> start = {0, 0};pair<int, int> end = {3, 3};int shortest = bfsShortestPath(grid, start, end);if (shortest != -1) {cout << "最短路径长度: " << shortest << endl;} else {cout << "无法到达终点!" << endl;}return 0;
}
五、路径回溯实现
扩展代码以记录路径:
vector<pair<int, int>> getPath(vector<vector<pair<int, int>>>& parent, pair<int, int> start, pair<int, int> end) {vector<pair<int, int>> path;pair<int, int> curr = end;while (curr != start) {path.push_back(curr);curr = parent[curr.first][curr.second];}path.push_back(start);reverse(path.begin(), path.end());return path;
}// 在BFS函数中添加父节点记录
vector<vector<pair<int, int>>> parent(n, vector<pair<int, int>>(m, {-1, -1}));
// ...
if (条件满足) {parent[x][y] = curr;
}
// 找到终点后调用getPath
六、复杂度分析
-
时间复杂度:O(N×M),每个节点处理一次。
-
空间复杂度:O(N×M),队列和距离矩阵的开销。
七、适用场景与限制
-
适用:无权图、网格迷宫、社交网络层级关系。
-
限制:仅处理无权图,带权图需改用Dijkstra或A*算法。
通过以上实现,BFS能够高效解决无权图中的最短路径问题。正确管理队列和状态标记是保证算法正确性的关键。
相关文章:
深入解析BFS算法:C++实现无权图最短路径的高效解决方案
在无权图中,广度优先搜索(BFS)是解决最短路径问题的高效算法。接下来博主从专业角度深入探讨其实现细节,并给出C代码示例: 目录 一、核心原理 二、算法步骤 三、C实现关键点 1. 数据结构 2. 边界检查 3. 路径回溯…...
LeetCode刷题---二分查找---441
排列硬币 441. 排列硬币 - 力扣(LeetCode) 题目 你总共有 n 枚硬币,并计划将它们按阶梯状排列。对于一个由 k 行组成的阶梯,其第 i 行必须正好有 i 枚硬币。阶梯的最后一行 可能 是不完整的。 给你一个数字 n ,计算…...
Unity结合Vuforia虚拟按键实现AR机械仿真动画效果
零、最终效果 待上传 一、资源准备 1、Vuforia Vuforia版本不能高于10.17.4(往上的版本虚拟按键功能被删除) 2、Unity Unity版本必须要高于2022.3.x,不然使用Vuforia插件时会出现bug 二、主要内容 1、添加虚拟按钮 2、为虚拟按钮设置…...
网络安全 linux学习计划 linux网络安全精要
🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 2.使用命令行 文件系统层次标准(FHS)是一个文件和目录在Unix和Linux操作系统上面应该如何存储的定义。 /bin 重要的二进制可执行程序/bo…...
深度解析2025最新微服务版本特性
当程序猿张三在凌晨三点对着满屏报错日志抓狂时,他绝对想不到2025年的微服务架构已经进化成了会哄睡的技术保姆。这年头要是谁家系统还像俄罗斯套娃般环环相扣,出门都不好意思跟同行打招呼。且看这群代码世界的乐高大师们,今年又给我们整了哪…...
世界棒球经典赛(World Baseball Classic)·棒球1号位
世界棒球经典赛(World Baseball Classic)是一项由美国职棒大联盟(MLB)和国际棒球总会(IBAF,现更名为世界棒垒球联盟WBSC)共同主办的国际棒球赛事。该赛事吸引了来自世界各地的顶尖棒球队伍参与&…...
为AI聊天工具添加一个知识系统 之115 详细设计之56 知识表征 之2
本文要点 要点 知识表征的顶级范畴中最好是先将九个原语primitive T, ⊥, Independent, Relative, Mediating, Physical, Abstract, Continuant,和 Occurrent 进行分组(分成2大组 和 4个小组)并写出它们的满足公司,然后将它们和三种设计&am…...
rust 实例化动态对象
在功能开发中,动态创建或获取某个对象的情况很多。在前端JS开发中,可以使用工厂函数,通过给定的类型标识创建不同的对象实例;还可以通过对象映射来实现动态创建对象。 在Rust中,我们也可以使用这两种方式去创建对象实…...
支持向量机 (Support Vector Machine, SVM)
支持向量机 (Support Vector Machine, SVM) 支持向量机(SVM)是一种广泛应用于分类、回归分析以及异常检测的监督学习算法。它基于结构风险最小化(Structural Risk Minimization,SRM)原则,通过寻找一个最优…...
C#初级教程(1)——C# 与.NET 框架:探索微软平台编程的强大组合
图片来源: https://www.lvhang.site/docs/dotnettimeline 即梦AI - 一站式AI创作平台 一、历史发展脉络 在早期的微软平台编程中,常用的编程语言有 Visual Basic、C、C。到了 20 世纪 90 年代末,Win32 API、MFC(Microsoft Found…...
Mac m1 连接公司内网
1、创建VPN 1、在系统偏好设置 2、选择网络 3、进行添加 2、添加设置 1、选择VPN 2、类型选择L2TP/IPSec 3、填写服务器IP和账号 4、点击认证设置-填写密码 。然后应用 3、进行特殊配置 网上说苹果系统的问题。 1、创建命令 sudo vim /etc/ppp/options 2、添加内容-主要别…...
C++:类与对象,定义类和构造函数
#define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> using namespace std; //如何让定义一个类 // 封装 // 1、将数据和方法定义到一起。 // 2、把想给你看的数据给你看,不想给你看的封装起来。 通过访问限定符来实现 class Stack { public: //1.成…...
杨校老师课堂之信息学奥赛结构体操作使用经典题集锦汇总
C基础:结构体数组综合训练 员工信息处理系统题目描述输入描述输出描述解题思路参考代码 员工信息处理系统 题目描述 在一家企业中,员工信息的准确性和时效性是日常人事管理工作的关键。由于企业员工数量众多,手动统计与更新员工信息不仅耗费大量时间&a…...
8. Flink-CDC
1. Flink-CDC的介绍 Flink-cdc主要是用来同步数据库中的数据,它的主要优势在于基于Flink框架直接用Flink Stream Api 或Flink SQL 直接编程,不需要引入第三方组件 2.Flink-CDC的使用 Flink-cdc在使用上需要注意的点 注意Flink-cdc在2.1版本之前需要导…...
Windows 权限结构和原理:深入浅出
一、什么是权限? 权限,是指在操作系统或应用程序中,某个对象(如用户、程序、设备等)对特定资源的可操作范围。具体来说,权限控制了一个主体(通常是用户或应用程序)对某个资源&#…...
Nginx环境安装
一、官网地址 Nginx官网:http://nginx.org/ Nginx中文网:https://nginx.p2hp.com/ 二、Nginx版本 mainline version 开发版本stableversion 稳定版本legacy version 历史版本 三、Windows系统安装Nginx 第一步:选择Windows版本,…...
Spring AI + Ollama 实现调用DeepSeek-R1模型API
一、前言 随着人工智能技术的飞速发展,大语言模型(LLM)在各个领域的应用越来越广泛。DeepSeek 作为一款备受瞩目的国产大语言模型,凭借其强大的自然语言处理能力和丰富的知识储备,迅速成为业界关注的焦点。无论是文本生…...
android系统SystemServer进程启动流程分析
目录 一,SystemServer整体框架 二,SystemServer启动源码分析 2.1,重要的概念 2.2,启动入口 2.3,创建对应进程的binder 三,binder驱动和binder线程池 四,SystemServer真正启动方法 4.1 SystemServer main方法里面主要做了几件事情 1)创建SystemServiceManager管理所有的…...
【雅思博客06】Daily Life
对话 A: Honey, the house is such a mess! I need you to help me tidy up a bit. My boss and her husband are coming over for dinner, and the house needs to be spotless! B: I’m in the middle of something right now. I’ll be there in a second. A: This can’t …...
Oracle 深入理解Lock和Latch ,解析访问数据块全流程
Oracle 锁机制介绍 根据保护对象的不同,单实例Oracle数据库锁可以分为以下几大类: DML lock(data locks,数据锁):用于保护数据的完整性; DDL lock(dictionary locks,字典…...
19、《Springboot+MongoDB整合:玩转文档型数据库》
SpringbootMongoDB整合:玩转文档型数据库 摘要:本文全面讲解Spring Boot与MongoDB的整合实践,涵盖环境搭建、CRUD操作、聚合查询、事务管理、性能优化等核心内容。通过15个典型代码示例,演示如何高效操作文档数据库,深…...
如何基于transformers库通过训练Qwen/DeepSeek模型的传统分类能力实现文本分类任务
文章目录 模型与环境准备文档分析源码解读模型训练及推理方式进阶:CPU与显存的切换进阶:多卡数据并行训练🔑 DDP 训练过程核心步骤🚫 DDP 不适用于模型并行⚖️ DDP vs. Model Parallelism⚙️ 解决大模型训练的推荐方法🎉进入大模型应用与实战专栏 | 🚀查看更多专栏…...
Unity中一个节点实现植物动态(Shader)
1 . 核心思路就操作顶点作往复运动; 核心代码: half stage1 dot(positionOS, float3(0, 1, 0)) * _Strength; half stage2 sin(dot(positionOS, float3(1, 0, 0)) * _Strength _Time.y * _Speed); half stage3 stage1 * stage2 * float3(0.001,…...
PrimeTime:工具简介
相关阅读 PrimeTimehttps://blog.csdn.net/weixin_45791458/category_12900271.html?spm1001.2014.3001.5482 PrimeTime是PrimeTime Suite中的一个工具,能够执行全芯片级、门级的静态时序分析,这是芯片设计和分析流程中的一个关键部分。该工具通过检查…...
FFmpeg+WebSocket+JsMpeg实时视频流实现方案
之前写的使用FFmpeg Nginx HLS流媒体播放方案,适合对实时性要求不高的需求,存在延迟,FFmpeg需要将视频流存储到本地文件,而本次方案FFmpeg不需要将视频流存储到本地文件,而是直接将转换后的视频流(如MJPE…...
《论系统需求分析方法》写作心得 - 系统分析师
系统需求分析方法论述 一、项目概述及本人职责 本人曾参与一项企业级客户关系管理系统(CRM)的开发项目,担任系统分析师的角色。该项目旨在为企业提供一个集客户信息管理、销售过程跟踪、客户服务支持于一体的综合管理平台,以提升…...
DuodooBMS源码解读之 mrp_management模块
制造管理扩展模块用户使用手册 一、模块概述 本扩展模块是基于 Odoo 18 开发的制造管理模块,主要为用户提供了更为强大和细致的制造管理功能。该模块添加了数量验证功能,即当一步工序未完成时,开始下一步工序,则下一步工序的生产…...
rust笔记8-Deref与隐式解引用强制转换
Rust 的智能指针和 Deref Trait 是 Rust 中非常重要的概念,它们使得 Rust 的引用和指针操作更加灵活和安全。下面我们将深入介绍 Deref Trait、Deref 与 &、* 运算符的关系,以及 Rust 的隐式解引用强制转换(Deref Coercion)。 1. 智能指针与 Deref Trait 智能指针(如…...
【拜读】Tensor Product Attention Is All You Need姚期智团队开源兼容RoPE位置编码
姚期智团队开源新型注意力:张量积注意力(Tensor Product Attention,TPA)。有点像一种「动态的LoRA」,核心思路在于利用张量分解来压缩注意力机制中的 Q、K、V 表示,同时保留上下文信息,减少内存…...
Docker-技术架构演进之路
目录 一、概述 常见概念 二、架构演进 1.单机架构 2.应用数据分离架构 3.应用服务集群架构 4.读写分离 / 主从分离架构 5.引入缓存 —— 冷热分离架构 6.垂直分库 7.业务拆分 —— 微服务 8.容器化引入——容器编排架构 三、尾声 一、概述 在进行技术学习过程中&am…...
