当前位置: 首页 > news >正文

图论算法入门:BFS 和 DFS 不是只差一个队列

图论算法入门:BFS 和 DFS 不是只差一个队列

一、遍历方式决定问题视角

BFS 和 DFS 都能遍历图,但它们适合的问题不同。BFS 一层层扩展,天然适合最短步数、层级关系和扩散过程;DFS 一条路走到底,适合连通性、回溯、拓扑关系和路径探索。不要把它们理解成“队列和栈的区别”这么浅。

刷题时,先问问题需要什么:最短路径还是枚举路径?需要层数还是需要深度?需要访问一次还是需要回溯撤销?答案会决定用 BFS 还是 DFS。

二、选择链路:看目标再选遍历

flowchart TD A[图问题] --> B{是否求最短步数} B -->|是| C[BFS] B -->|否| D{是否需要回溯或连通性} D -->|是| E[DFS] D -->|否| F[按题意建模]

如果边权都相同,BFS 第一次到达通常就是最短步数。如果有权重,就要考虑 Dijkstra 或其他算法。不要把 BFS 硬套到带权图上。

三、代码示例:网格最短路 BFS

from collections import deque def shortest_path(grid): m, n = len(grid), len(grid[0]) q = deque([(0, 0, 0)]) seen = {(0, 0)} dirs = [(1, 0), (-1, 0), (0, 1), (0, -1)] while q: x, y, d = q.popleft() if x == m - 1 and y == n - 1: return d for dx, dy in dirs: nx, ny = x + dx, y + dy if 0 <= nx < m and 0 <= ny < n and grid[nx][ny] == 0 and (nx, ny) not in seen: seen.add((nx, ny)) q.append((nx, ny, d + 1)) return -1

这里seen入队时就标记,避免同一个点重复入队。很多 BFS 超时,不是思路错,而是标记时机错。

四、工程边界:建图比遍历更容易错

图论题常常难在建图。字符串转换、课程依赖、岛屿网格、社交关系,本质都是图,但节点和边要自己抽象。建错图,遍历再熟也没用。写题解时要明确节点是什么,边表示什么,是否有向,是否有权。

取舍方面,邻接表适合稀疏图,邻接矩阵适合稠密图或快速判断边是否存在。复杂度也要跟着结构说清楚。V是点数,E是边数,BFS/DFS 通常是 O(V+E),但网格题可以写成 O(mn)。

递归 DFS 还要注意栈深。Python 遇到大图可能递归爆栈,必要时改成显式栈。算法题里能 AC 的写法,放到工程里不一定稳。边界意识要从刷题时就培养。

图论题还要警惕重复访问。无向图 DFS 时,如果只判断当前节点,没处理父节点,很容易在两点之间来回递归;BFS 如果出队时才标记,可能同一个节点被多次入队,复杂度直接膨胀。访问标记的时机,是图论代码的基本功。

对于拓扑排序,要区分 BFS 版 Kahn 算法和 DFS 版后序。Kahn 算法能更直观看到入度变化,也更容易判断是否有环;DFS 版写起来短,但状态标记要分未访问、访问中、已完成。题解里说清这个区别,读者更不容易混。

五、总结

BFS 和 DFS 不只是队列和栈的区别。BFS 适合层级和最短步数,DFS 适合连通性和路径探索。图论题先建模,再选遍历,最后讲清复杂度和边界。

http://www.jsqmd.com/news/1112444/

相关文章:

  • 思源宋体CN字体配置与排版优化完全指南:7种字重深度解析
  • Algorithm001:双指针算法01
  • 爬虫转大模型:换个角度,把核心能力写进作品集
  • Qwen3-VL-8B Web系统安全加固实战:HTTPS、CSRF与XSS防护
  • Moneta Markets亿汇:“芯片目标价推升风险偏好”
  • 网盘直链下载助手:九大网盘高速下载完整指南
  • vscode中claude插件的内联差异inline diff窗口不正常显示解决办法
  • 自媒体运营分析-作品特征构建
  • 7-Zip完全指南:免费开源压缩软件如何帮你节省50%存储空间
  • Three.js 模型反射效果教程
  • 基于CLIP的文本可控PET医学影像降噪技术研究
  • 第 41 篇:WebSocket——从HTTP握手到全双工长连接
  • 数据分析转大模型:报表到智能分析 Agent,用业务场景检验技术取舍
  • AI 生成组件测试:先定义行为,再让模型补用例
  • 032、混合注意力新范式:HAT混合注意力Transformer的设计思想与复现指南
  • ConfigMap 和 Secret:配置能热更新,不代表可以随便改
  • 极限竞速地平线4/5游戏修改神器:Forza Mods AIO的3大核心解决方案
  • TVA在具身智能技术演进中的独特价值(6)
  • ClickHouse 分区设计:分区不是越细越好
  • MySQL Binlog 一致性:别只检查有没有开启
  • 分库分表设计:先确认业务边界,再选择分片键
  • FP32近似乘法器在CNN中的优化设计与应用
  • Node.js 轻量任务队列:独立产品先把失败处理写清楚
  • 流式响应实现:Token 出来了,不代表用户体验好了
  • TDD在Unity3D游戏项目开发中的实践0x00
  • 定时任务调度:schedule与APScheduler
  • -一名3年工作经验的程序员应该具备的技能
  • Vatee万腾:聚焦细节,看看外汇领域风控思路的关键维度
  • ClickHouse 物化视图:快是快,但口径要守住
  • 开源文档站:搜索体验比首页大图更重要