算法中DFS & BFS 核心学习笔记

📚 DFS & BFS 核心学习笔记

一句话总结:BFS是"广撒网"逐层推进,DFS是"深挖掘"一条路走到黑


🎯 核心思想对比

BFS - 广度优先搜索

复制代码
🌊 水波纹扩散法:先近后远,逐层推进
  • 口号:"一圈一圈往外荡"
  • 数据结构 :队列 Queue (FIFO)
  • 比喻:往池塘扔石头,波纹一圈圈扩散

DFS - 深度优先搜索

复制代码
🪜 楼梯下潜法:一路向下,不撞南墙不回头
  • 口号:"一条路走到黑"
  • 数据结构 :栈 Stack (LIFO) 或 递归
  • 比喻:走迷宫,选一条路一直走,走不通再回溯

📊 可视化遍历顺序

图结构:

复制代码
    A
   /|\
  B C D
  |
  E
搜索类型 访问顺序 特点
BFS A → B → C → D → E 先访问完所有直接邻居
DFS A → B → E → C → D 沿一条路径深入到底

💾 空间复杂度对比

BFS - 横向膨胀

python 复制代码
# 最坏情况:存储整层节点
Queue = [A, B, C, D, E, ...]  # 可能指数级增长
  • 复杂度:O(最大宽度)
  • 树形图:最坏 2^h (h=深度)
  • 优点:适合稀疏图

DFS - 纵向深入

python 复制代码
# 只需存储当前路径
Stack = [A, B, E]  # 最多深度个节点
  • 复杂度:O(最大深度)
  • 树形图:最坏 h (h=深度)
  • 优点:通常更省内存

🎪 经典应用场景

✅ BFS 擅长

场景 原因
最短路径 天然一层=一步,保证最短
橘子腐烂 每分钟感染一层,精准计时
社交网络 "六度人脉"找最短关系链
地图导航 寻找最少换乘/最短距离

✅ DFS 擅长

场景 原因
环检测 深度递归,撞环即返
连通分量 一次遍历标记所有相连节点
拓扑排序 深度优先完成依赖
回溯问题 全排列、子集天然适合递归

💻 代码模板速查

BFS 模板(橘子腐烂风格)

python 复制代码
from collections import deque

def bfs(start):
    queue = deque([start])
    visited = set([start])
    
    while queue:
        node = queue.popleft()  # 关键:先进先出
        for neighbor in node.neighbors:
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append(neighbor)

DFS 模板(课程依赖风格)

python 复制代码
# 递归版(最常用)
def dfs(node, visited, path):
    if node in path:  # 检测环
        return True
    if node in visited:
        return False
    
    visited.add(node)
    path.add(node)
    
    for neighbor in node.neighbors:
        if dfs(neighbor, visited, path):
            return True
    
    path.remove(node)
    return False

# 迭代版(避免递归深度限制)
def dfs_iterative(start):
    stack = [start]
    visited = set()
    
    while stack:
        node = stack.pop()  # 关键:后进先出
        if node not in visited:
            visited.add(node)
            for neighbor in node.neighbors:
                stack.append(neighbor)

🎯 选型决策树

复制代码
问题:需要找"最短路径/最少步数"?
  ├─ 是 → BFS
  └─ 否 → 继续判断

问题:需要检测"是否有环"?
  ├─ 是 → DFS
  └─ 否 → 继续判断

问题:空间是否紧张?
  ├─ 是 → DFS
  └─ 否 → 两者皆可,看实现偏好

🧠 记忆口诀

BFS 口诀

复制代码
队列先进先出,一层一层剥开
波纹扩散自然,最短路径首选

DFS 口诀

复制代码
栈或递归实现,深度优先挖掘
一条路走到黑,环检测神器

⚡ 快速对比表

特性 BFS DFS
顺序 横向逐层 纵向深入
空间 O(宽度) O(深度)
最短路径 ✅ 保证 ❌ 不保证
环检测 ⚠️ 可以但繁琐 ✅ 天然适合
实现 队列迭代 递归/栈
适用 距离、层级 连通、环、回溯

💡 实战技巧

  1. 看到"最短"想BFS:最少步数、最少时间、最少操作
  2. 看到"环"想DFS:检测循环依赖、死锁
  3. 空间爆炸用DFS:图很宽但不深时
  4. 递归太深用BFS:避免栈溢出
  5. 多源起点:BFS可天然多起点同时开始(如橘子腐烂)

最后提醒 :两者时间复杂度都是 O(V+E),选型关键看问题需求 和空间限制!

相关推荐
I_belong_to_jesus6 小时前
C++关于分支预测的优化1
开发语言·c++·算法
Code_Solitude13 小时前
C语言动态内存 + 柔性数组 + 数组名退化
c语言·算法·柔性数组
上海潭龙东海科技有限公司13 小时前
客运站管控之动态孪生技术方案(新增一屏管控模块
数据仓库·人工智能·算法·重构·动态规划
YLCHUP15 小时前
【思维&图论建模】题解:债权(debt)_图论_建模_思路转化_思维题目_C++算法竞赛
c++·笔记·算法·数学建模·贪心算法·深度优先·图论
思麟呀16 小时前
背包DP(01背包+完全背包)
c++·算法
笑容掩饰我的失落17 小时前
区块链从小白到精通(七):Solidity 语法精讲——数据类型、函数、修饰器与事件
算法·区块链·php·智能合约·哈希算法
Pniubi18 小时前
力扣24. 两两交换链表中的节点(递归)
算法·leetcode·链表
꧁细听勿语情꧂18 小时前
直接选择排序,堆排序,冒泡排序,递归快速排序、hoare版本、挖坑法、lomuto前后指针,非递归快速排序
c语言·开发语言·数据结构·算法
俊俊几年的19 小时前
动态规划(Dynamic Programming)详解:从入门到 LeetCode Hot 100
linux·c++·算法·leetcode·嵌入式·动态规划·c