c++如何实现广度优先搜索_c++ BFS算法实现【源码】

发布时间 - 2026-01-26 00:00:00    点击率:
标准BFS遍历用std::queue实现:取队首节点,访问其未访问邻接点并入队;邻接表用std::vector节省空间,visited数组防重复入队。

std::queue 实现标准 BFS 遍历

核心就是维护一个先进先出的队列,每次取出队首节点,访问它所有未访问过的邻接点并入队。C++ 标准库的 std::queue 是最直接的选择,不需要手写队列结构。

关键点:

  • std::vector<:vector>> 存邻接表,比邻接矩阵更省空间(尤其稀疏图)
  • std::vector 记录访问状态,下标即节点编号,避免重复入队
  • 入队前必须检查是否已访问,否则可能无限循环或结果错乱

示例片段(无向图):

std::vector> graph = {{1,2}, {0,3}, {0,3}, {1,2}};
std::vector visited(graph.size(), false);
std::queue q;
q.push(0);
visited[0] = true;

while (!q.empty()) {
    int u = q.front(); q.pop();
    std::cout << u << " ";
    for (int v : graph[u]) {
        if (!visited[v]) {
            visited[v] = true;
            q.push(v);
        }
    }
}

处理带权图或需要路径还原的 BFS

BFS 本身不适用于带权图的最短路径(除非所有边权相等),但若图中边权均为 1,BFS 天然给出单源最短距离;若还需知道怎么走到的,就得额外记录父节点。

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

常见做法:

  • 加一个 std::vector parent,初始化为 -1,每次从 u 扩展到 v 时设 parent[v] = u
  • 距离数组 dist 可用 std::vector,初始填 -1 或 INT_MAXdist[source] = 0,之后 dist[v] = dist[u] + 1
  • 路径还原时从目标节点不断跳 parent,直到 -1,再逆序输出

遇到 “超时” 或 “内存爆炸” 怎么办

不是算法逻辑错,而是数据结构或边界没控住。典型诱因:

  • 图节点数极大(比如 1e5),但用了二维邻接矩阵(vector>(n, vector(n))),直接 O(n²) 内存炸掉 → 改用邻接表
  • 没判重就 push 进队列,导致同一节点反复入队(比如无向图中 u→v 后又 v→u),队列迅速膨胀 → 必须在 push 前查 visited[v]
  • 输入格式含自环或重边,虽不影响正确性,但会徒增遍历次数 → 可在建图时去重,或依赖 visited 自然过滤

和 DFS 混用时容易踩的坑

BFS 和 DFS 共享同一张图、同一套 visited 数组时,顺序和结果会互相干扰。实际项目中常见错误:

  • 先跑一遍 BFS 把 visited 全设为 true,接着调 DFS 却发现“什么都没走” → 解决:每次搜索前重置 visited,或用局部变量
  • 误以为 BFS 能像 DFS 那样方便回溯(比如找所有路径),但 BFS 天然不保存路径分支 → 真要枚举所有路径,得用 DFS 或改造 BFS 存完整路径(空间代价高)
  • 多源 BFS(如多个起点同时开始)忘记把所有起点一次性 push 到队列并标记 → 结果只从第一个起点展开

真正难的不是写对一次 BFS,而是清楚它在哪种图结构、哪种问题约束下依然可靠——比如节点编

号不连续、图用字符串 ID 而非整数、或者需要实时中断搜索。这些场景下,队列元素类型和访问标记方式都得跟着变。


# c++  # 标准库  # 局部变量  # 字符串  # 循环  # 数据结构  # 算法  # 遍历  # 哪种  # 最短  # 图中  # 第一个  # 多个  # 不需要  # 走到  # 设为  # 均为 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Win11怎样安装网易有道词典_Win11安装词典教程【步骤】  Laravel如何获取当前登录用户信息_Laravel Auth门面使用与Session用户读取【技巧】  制作旅游网站html,怎样注册旅游网站?  如何在万网ECS上快速搭建专属网站?  怎么用AI帮你为初创公司进行市场定位分析?  如何快速搭建高效可靠的建站解决方案?  Midjourney怎么调整光影效果_Midjourney光影调整方法【指南】  Laravel如何实现登录错误次数限制_Laravel自带LoginThrottles限流配置【方法】  laravel怎么使用数据库工厂(Factory)生成带有关联模型的数据_laravel Factory生成关联数据方法  Swift中循环语句中的转移语句 break 和 continue  大同网页,大同瑞慈医院官网?  Laravel怎么调用外部API_Laravel Http Client客户端使用  js实现获取鼠标当前的位置  如何在IIS服务器上快速部署高效网站?  在线制作视频网站免费,都有哪些好的动漫网站?  Laravel如何自定义错误页面(404, 500)?(代码示例)  Laravel怎么配置不同环境的数据库_Laravel本地测试与生产环境动态切换【方法】  Laravel怎么写单元测试_PHPUnit在Laravel项目中的基础测试入门  JavaScript数据类型有哪些_如何准确判断一个变量的类型  如何在企业微信快速生成手机电脑官网?  如何快速搭建高效简练网站?  Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置  Laravel如何处理异常和错误?(Handler示例)  香港服务器建站指南:免备案优势与SEO优化技巧全解析  Laravel如何使用集合(Collections)进行数据处理_Laravel Collection常用方法与技巧  Laravel如何处理表单验证?(Requests代码示例)  详解jQuery中的事件  Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制  Swift开发中switch语句值绑定模式  javascript基本数据类型及类型检测常用方法小结  什么是JavaScript解构赋值_解构赋值有哪些实用技巧  成都品牌网站制作公司,成都营业执照年报网上怎么办理?  laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法  Laravel如何操作JSON类型的数据库字段?(Eloquent示例)  如何在 Go 中优雅地映射具有动态字段的 JSON 对象到结构体  企业网站制作这些问题要关注  Laravel怎么清理缓存_Laravel optimize clear命令详解  音响网站制作视频教程,隆霸音响官方网站?  如何打造高效商业网站?建站目的决定转化率  Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载  Laravel中Service Container是做什么的_Laravel服务容器与依赖注入核心概念解析  如何实现javascript表单验证_正则表达式有哪些实用技巧  今日头条AI怎样推荐抢票工具_今日头条AI抢票工具推荐算法与筛选【技巧】  如何用y主机助手快速搭建网站?  移动端脚本框架Hammer.js  车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?  再谈Python中的字符串与字符编码(推荐)  laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法  Laravel如何创建和注册中间件_Laravel中间件编写与应用流程  Laravel怎么实现模型属性转换Casting_Laravel自动将JSON字段转为数组【技巧】