0

0

c++中如何实现广度优先搜索_c++ BFS算法图论遍历方法【汇总】

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-01-22 18:45:10

|

810人浏览过

|

来源于php中文网

原创

std::queue 是 C++ 中实现 BFS 最常用方式,需配合访问标记数组避免重复入队,且标记必须在入队时设置;图可用邻接表或邻接矩阵表示,稀疏图推荐邻接表。

c++中如何实现广度优先搜索_c++ bfs算法图论遍历方法【汇总】

std::queue 实现标准 BFS 遍历

广度优先搜索在 C++ 中最常用、最直观的实现方式是借助 std::queue,配合访问标记数组(或 std::set/std::unordered_set)避免重复入队。核心逻辑是:从起点入队 → 循环取队首 → 访问所有未访问邻接点并入队。

关键点:

  • std::queue 是 FIFO 容器适配器,不支持随机访问或遍历,但完全满足 BFS 层序需求
  • 图可用邻接表(vector>)或邻接矩阵(vector>)表示;稀疏图强烈推荐邻接表
  • 访问标记必须在入队时设置(而非出队时),否则同一节点可能被多次加入队列
vector> graph = {{1,2}, {0,3}, {0,3}, {1,2}};
vector visited(graph.size(), false);
queue q;
q.push(0);
visited[0] = true;

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

处理带权图或需要记录距离时用 pair 或结构体

纯 BFS 仅适用于无权图或所有边权相等的情形。若需在 BFS 过程中同步维护节点距离(如求最短路径长度),常见做法是把 nodedist 绑定为 pair 入队。

注意:

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

  • 不要用 queue 配合外部数组“延迟更新”距离——这会导致距离值与实际出队顺序错位
  • 如果边权不全为 1(比如有权重为 2 的边),BFS 不再适用,应改用 Dijkstra 算法
  • 若图含负权边,Dijkstra 也不适用,需考虑 Bellman-Ford 或 SPFA
queue> q; // {node, dist}
q.push({0, 0});
vector dist(graph.size(), -1); // -1 表示未访问
dist[0] = 0;

while (!q.empty()) {
    auto [u, d] = q.front(); q.pop();
    for (int v : graph[u]) {
        if (dist[v] == -1) {
            dist[v] = d + 1;
            q.push({v, d + 1});
        }
    }
}

多源 BFS:多个起点同时入队

当问题要求“从任意一个起点出发的最短距离”(如矩阵中多个 '0' 扩散到 '1'),可将所有起点一次性压入队列,并初始化对应距离为 0。这本质上仍是标准 BFS,只是初始队列非单元素。

Remove.bg
Remove.bg

AI在线抠图软件,图片去除背景

下载

典型场景包括:

  • 01 矩阵中每个位置到最近 0 的距离
  • 腐烂橘子传播时间
  • 双向 BFS 的前半部分初始化

陷阱:

  • 误写成循环中逐个 push 再单独处理——这样会破坏层序性,必须所有起点先入队、再统一开始 while 循环
  • 忘记对多个起点也做访问标记,导致重复入队

避免常见内存与逻辑错误

BFS 在 C++ 中容易因容器误用或边界疏忽引发崩溃或死循环:

  • 图节点编号从 0 开始,但 graph.size() 可能小于最大节点 ID —— 若输入含孤立大编号点(如节点 100 但只有 5 条边),需用 max_node_id + 1 初始化 visiteddist
  • queue::front()queue::pop() 是两个独立操作,不能省略 pop(),否则无限循环
  • 使用 vector> 存图时,确保每行都已 resize 或用 push_back 正确构建,空行会导致范围访问越界
  • 在类成员函数中复用 queue 时,记得每次调用前 queue = queue() 清空(C++11 后可直接赋值空队列)

图论 BFS 看似简单,真正难的是根据题意准确建模——节点定义、边是否存在、是否允许回头、距离含义是否随层变化,这些细节一旦错,整个 BFS 就偏离目标。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
while的用法
while的用法

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

91

2023.09.25

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

197

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

190

2025.07.04

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

338

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

542

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

53

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

197

2025.08.29

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

404

2023.08.14

Golang 性能分析与pprof调优实战
Golang 性能分析与pprof调优实战

本专题系统讲解 Golang 应用的性能分析与调优方法,重点覆盖 pprof 的使用方式,包括 CPU、内存、阻塞与 goroutine 分析,火焰图解读,常见性能瓶颈定位思路,以及在真实项目中进行针对性优化的实践技巧。通过案例讲解,帮助开发者掌握 用数据驱动的方式持续提升 Go 程序性能与稳定性。

9

2026.01.22

热门下载

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

精品课程

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

共94课时 | 7.3万人学习

C 教程
C 教程

共75课时 | 4.2万人学习

C++教程
C++教程

共115课时 | 13.3万人学习

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

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