0

0

C++怎么实现广度优先搜索BFS_C++图遍历逻辑【实战】

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-03-12 19:49:34

|

868人浏览过

|

来源于php中文网

原创

用 std::queue 实现 BFS 最稳,因其底层基于 std::deque 或 std::list 保证 O(1) 入队出队,避免 vector 模拟时 erase 头部导致 O(n) 复杂度;需独立初始化 visited 数组并入队前标记,邻接表优先用 vector 而非 map 以提升缓存效率;节点规模适配 n ≤ 1e5、m ≤ 2e5;路径还原应使用 parent 数组而非字符串拼接。

c++怎么实现广度优先搜索bfs_c++图遍历逻辑【实战】

std::queue 实现 BFS 最稳,别手写队列

标准库的 std::queue 是 BFS 的天然搭档,底层用 std::deque(默认)或 std::list 都能保证 O(1) 入队出队。自己用 vector 模拟队列容易在 pop 时误删头元素导致 O(n) 复杂度,一跑稀疏图就卡顿。

常见错误现象:vector.erase(vector.begin()) 反复调用;或者用 vector[0] 取头但忘了 erase 后索引全偏移。

  • 初始化:用 std::queue<int></int> 存节点编号,配合邻接表 vector<vector>></vector>
  • 访问标记必须独立于队列——用 vector<bool> visited(n, false)</bool>,别靠队列是否为空判断“是否处理过”
  • 入队前立刻设 visited[u] = true,否则同一节点可能被多次加入(尤其无向图)

邻接表存图时,vector<vector>></vector>map<int vector>></int> 快得多

除非节点编号稀疏且跨度极大(比如只有 1 和 1e9 两个点),否则用哈希表存邻接关系纯属拖慢 BFS。下标访问是连续内存,vector<vector>></vector> 的 cache 局部性好,遍历邻居时 CPU 预取有效。

使用场景:节点数 n ≤ 1e5,边数 m ≤ 2e5 —— 这是典型竞赛/工程图规模。

立即学习C++免费学习笔记(深入)”;

腾讯交互翻译
腾讯交互翻译

腾讯AI Lab发布的一款AI辅助翻译产品

下载
  • 建图:对每条边 u → v,执行 graph[u].push_back(v);无向图则再加 graph[v].push_back(u)
  • 注意:节点编号通常从 0 或 1 开始,初始化 graph 大小别写错,比如 vector<vector>> graph(n + 1)</vector>
  • 如果输入含重边,BFS 本身不敏感,但 visited 能自然去重;若需严格去重建图,可先用 set 收集再转 vector,但一般没必要

visited 数组漏初始化或大小不对,直接导致无限循环或越界

这是最常打断调试的硬伤。BFS 一旦把未标记的节点反复压入队列,程序要么 SIGSEGV(访问非法内存),要么死循环(队列永远不空)。

错误信息示例:vector::_M_range_check: __n (which is 123456789) >= this->size() (which is 1000),或程序卡住不动、CPU 占满。

  • 务必在 BFS 前完成初始化:vector<bool> visited(n, false)</bool>,其中 n 是最大可能节点编号 + 1
  • 如果图节点编号不连续(如只给了 500 个点,编号是随机的 1000~1999),得先离散化,或改用 unordered_map<int bool></int>,但性能下降明显
  • 别用 int visited[N] 这种静态数组——N 写小了越界,写大了栈溢出(尤其递归+大数组混用时)

需要路径还原?别在 BFS 里拼字符串,存 parent 数组最轻量

BFS 本身不记录路径,但多数实际需求(比如找最短路、输出方案)都需要回溯。拼接字符串或 vector 在每次入队时拷贝,时间空间双爆炸。

性能影响:字符串拼接平均 O(L)(L 是路径长度),总复杂度退化到 O(n²);而 parent 数组只需 O(1) 写 + O(L) 回溯。

  • 声明:vector<int> parent(n, -1)</int>,初始节点的 parent[start] = start 或保持 -1
  • 当从 u 扩展到 v 时,写 parent[v] = u,仅此一句
  • 还原路径:用 while 循环从终点往回跳 parent,用 stack<int></int> 或逆序 vector 收集,避免递归栈深问题
多源 BFS、带权图、终止条件提前判断这些属于延伸场景,基础 BFS 稳住这四点,90% 的图遍历需求不会翻车。真正容易被忽略的是:visited 初始化时机和 parent 数组的索引一致性——它们不出错时毫无存在感,一错就是核心逻辑崩掉。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

106

2023.09.25

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

760

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1566

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

649

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

1228

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

1204

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

192

2025.07.29

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 11.2万人学习

C 教程
C 教程

共75课时 | 5.4万人学习

C++教程
C++教程

共115课时 | 21.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号