算法宗门---广度有优先搜索BFS

广度优先搜索(BFS,Breadth-First Search)

一、BFS 的 "生活化故事":像找迷宫出口一样 "层层扩散"

你可以把 BFS 想象成 "小时候玩迷宫的最稳妥办法":假设你站在迷宫的起点,想找到出口,但你分不清哪条路是对的。这时你不会一头扎进某条路死磕(那是深度优先搜索 DFS),而是先把离你一步之遥的所有路口 都标记出来(这些是 "第一层");然后从这些第一层路口出发,再把离它们一步之遥、且没被标记过的路口 标记出来("第二层");以此类推,直到某一层的人喊 "我找到出口了!"------ 这就是 BFS 的核心逻辑:层层递进、地毯式搜索

从学术角度说,BFS 的雏形最早出现在 19 世纪数学家康托尔、若尔当对图结构的研究中,后来被系统应用到计算机领域。它没有 "一个人灵光一闪发明" 的戏剧性故事,但它的思路完全贴合普通人的直觉 ------ 比如你想找朋友圈里和你隔 3 个人的好友,就是先找直接好友(1 层)、再找他们的好友(2 层)、最后找这层人的好友(3 层),直到找到目标。

二、BFS 的核心作用:解决 "步数最少" 的问题

BFS 的核心价值就在于 "层层扩散" 的特性,主要能解决两类问题:

  1. 最核心 :在无权图(所有边没有权重 / 权重都相同) 中,找到从起点到目标的最短路径(步数最少) ------ 比如迷宫里 "最少走几步到出口"、朋友圈 "你和 XX 隔了几个人";
  2. 其他常用作用
    • 遍历图 / 树的所有节点(比如爬虫从一个网页出发,爬完整个网站的所有页面);
    • 判断两个节点是否可达(比如判断迷宫里起点能不能到出口、两个用户是否在同一个社交网络里);
    • 找离起点最近的所有目标(比如找你家周边 1 公里内的所有超市)。

三、BFS 的具体可执行代码(朋友圈找人示例)

下面用 "找朋友圈里和你隔几步的好友" 为例,写一个通俗易懂的 BFS 代码,注释详细,可直接复制运行。

python 复制代码
from collections import deque

def bfs_friend_circle(friend_graph, start_person, target_person):
    """
    BFS实现:找朋友圈中从start_person到target_person的最短步数(隔几个人)
    :param friend_graph: 朋友圈关系图,格式为 {人: [好友列表], ...}
    :param start_person: 起点(你)
    :param target_person: 目标(要找的人)
    :return: 最短步数(比如直接好友返回1,无交集返回-1),最短路径(比如["你", "张三", "李四"])
    """
    # 1. 异常处理:起点/目标不在朋友圈里
    if start_person not in friend_graph or target_person not in friend_graph:
        return -1, []
    # 2. 特殊情况:找自己
    if start_person == target_person:
        return 0, [start_person]
    
    # 3. 初始化:队列(存储待探索的人+当前步数+路径),已访问集合(避免重复找)
    # deque是Python的双端队列,popleft()效率高,适合BFS的"先进先出"
    queue = deque()
    queue.append((start_person, 0, [start_person]))  # (当前人, 步数, 路径)
    visited = set()
    visited.add(start_person)
    
    # 4. 核心循环:层层探索好友
    while queue:
        # 取出队列最前面的人(保证"层层处理")
        current_person, current_step, current_path = queue.popleft()
        
        # 遍历当前人的所有好友
        for friend in friend_graph[current_person]:
            # 如果好友是目标,直接返回结果
            if friend == target_person:
                new_path = current_path + [friend]
                return current_step + 1, new_path
            
            # 如果好友没被访问过,加入队列继续探索
            if friend not in visited:
                visited.add(friend)
                new_path = current_path + [friend]
                queue.append((friend, current_step + 1, new_path))
    
    # 5. 遍历完都没找到,说明无交集
    return -1, []

# ------------------- 测试代码 -------------------
if __name__ == "__main__":
    # 构建朋友圈关系图
    # 说明:"你"的好友是"张三""李四";"张三"的好友是"你""王五";"王五"的好友是"张三""赵六";以此类推
    friend_graph = {
        "你": ["张三", "李四"],
        "张三": ["你", "王五"],
        "李四": ["你", "赵六"],
        "王五": ["张三", "赵六"],
        "赵六": ["李四", "王五", "孙七"],
        "孙七": ["赵六"],
        "周八": ["吴九"],
        "吴九": ["周八"]
    }
    
    # 测试1:找"你"到"孙七"的最短步数和路径
    step, path = bfs_friend_circle(friend_graph, "你", "孙七")
    if step == -1:
        print("你和孙七不在同一个朋友圈里")
    else:
        print(f"你到孙七最短需要隔{step}个人,路径:{' -> '.join(path)}")
    
    # 测试2:找"你"到"周八"的最短步数和路径
    step2, path2 = bfs_friend_circle(friend_graph, "你", "周八")
    if step2 == -1:
        print("\n你和周八不在同一个朋友圈里")
    else:
        print(f"你到周八最短需要隔{step2}个人,路径:{' -> '.join(path2)}")
代码运行结果
复制代码
你到孙七最短需要隔3个人,路径:你 -> 张三 -> 王五 -> 赵六 -> 孙七

你和周八不在同一个朋友圈里
代码关键部分解释
  1. 队列(deque):BFS 的核心工具,用 "先进先出" 保证 "层层处理"------ 先处理完 "你" 的直接好友,再处理好友的好友,不会漏掉任何一层;
  2. 已访问集合(visited):避免重复探索(比如 "你" 找 "张三","张三" 又找 "你",会无限循环);
  3. 路径记录:每个队列元素都带 "当前路径",找到目标时直接返回完整路径,不用额外回溯;
  4. 步数计算:每往下一层,步数 + 1,保证返回的是 "最少步数"。

四、总结

  1. 故事核心:BFS 像 "迷宫里层层找出口",核心是 "先进先出、地毯式扩散",没有戏剧性发明故事,但贴合日常思维;
  2. 核心作用:解决无权图的 "最短步数" 问题,还能遍历图、判断节点是否可达(比如朋友圈是否有交集);
  3. 代码关键:用队列(deque)实现 "层层处理",用已访问集合避免循环,是入门图算法的首选。
相关推荐
独自破碎E9 小时前
【归并】数组中的逆序对
java·数据结构·算法
f***24119 小时前
MATLAB高效算法优化实战指南
开发语言·算法·matlab
Blossom.11810 小时前
大模型自动化压缩:基于权重共享的超网神经架构搜索实战
运维·人工智能·python·算法·chatgpt·架构·自动化
优选资源分享10 小时前
MD5 哈希值校验工具 v1.5.3 实用文件校验工具
算法·哈希算法
AI科技星10 小时前
能量绝对性与几何本源:统一场论能量方程的第一性原理推导、验证与范式革命
服务器·人工智能·科技·线性代数·算法·机器学习·生活
Coder_Boy_10 小时前
基于SpringAI的在线考试系统-数据库表设计
java·数据库·算法
散峰而望10 小时前
【算法竞赛】链表和 list
数据结构·c++·算法·链表·list·哈希算法·推荐算法
爱编程的小吴10 小时前
【力扣练习题】55. 跳跃游戏
算法·leetcode
春日见10 小时前
控制算法:PID算法
linux·运维·服务器·人工智能·驱动开发·算法·机器人