不同情况下的BFS模版


1️⃣ 标准 BFS 模板(遍历整个图)

适用于一般的 无向图 / 有向图 遍历,不计算最短路径,仅用于层序遍历找到目标点

from collections import deque

def bfs(graph, start):
    queue = deque([start])  # BFS 队列
    visited = set([start])  # 记录访问过的节点

    while queue:
        node = queue.popleft()  # 取出当前节点
        print(node)  # 处理当前节点(这里是打印)

        for neighbor in graph[node]:  # 遍历所有邻居
            if neighbor not in visited:
                visited.add(neighbor)  # 标记访问
                queue.append(neighbor)  # 入队

2️⃣ 单次 BFS 计算最短路径(无权图)

适用于 无向图 / 有向图,求从起点到所有点的最短路径

from collections import deque

def bfs_shortest_path(n, edges, start=0):
    graph = [[] for _ in range(n)]  # 构建邻接表
    for u, v in edges:
        graph[u].append(v)
        graph[v].append(u)

    queue = deque([start])
    distance = [-1] * n  # -1 表示未访问
    distance[start] = 0

    while queue:
        node = queue.popleft()
        for neighbor in graph[node]:
            if distance[neighbor] == -1:  # 还未访问
                distance[neighbor] = distance[node] + 1
                queue.append(neighbor)

    return distance

适用条件:图是无权重的,每条边权值相同。


3️⃣ BFS 寻找最短路径(带路径回溯)

适用于 无向图 / 有向图,求 startend 的最短路径,并返回路径。

from collections import deque

def bfs_find_path(graph, start, end):
    queue = deque([(start, [start])])  # 记录路径
    visited = set([start])

    while queue:
        node, path = queue.popleft()

        if node == end:
            return path  # 找到路径,直接返回

        for neighbor in graph[node]:
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append((neighbor, path + [neighbor]))  # 更新路径

    return []  # 若无路径返回空列表

适用条件无权图最短路径问题,但需要返回具体路径。


4️⃣ 迷宫求解 / 二维网格 BFS

适用于 二维矩阵 / 迷宫 / 棋盘格,用于寻找最短路径或遍历所有可达点。

from collections import deque

def bfs_maze(grid, start):
    rows, cols = len(grid), len(grid[0])
    directions = [(-1,0), (1,0), (0,-1), (0,1)]  # 上下左右移动
    queue = deque([start])  # BFS 队列
    visited = set([start])

    while queue:
        x, y = queue.popleft()
        print(f"访问: {(x, y)}")  # 处理当前点

        for dx, dy in directions:  # 遍历四个方向
            nx, ny = x + dx, y + dy
            if 0 <= nx < rows and 0 <= ny < cols and grid[nx][ny] == 0 and (nx, ny) not in visited:
                visited.add((nx, ny))
                queue.append((nx, ny))  # 入队

# 示例迷宫:0 表示可走,1 表示障碍物
maze = [
    [0, 0, 1, 0],
    [1, 0, 1, 0],
    [0, 0, 0, 0]
]
bfs_maze(maze, (0, 0))

适用条件:网格地图、迷宫、棋盘等二维 BFS 问题。


5️⃣ 双向 BFS(适用于搜索空间大的情况)

适用于 起点到终点的最短路径,相比普通 BFS 更快

from collections import deque

def bidirectional_bfs(graph, start, end):
    if start == end:
        return 0

    front_queue = deque([start])
    back_queue = deque([end])
    front_visited = {start: 0}
    back_visited = {end: 0}

    while front_queue and back_queue:
        # 从前向后扩展
        node = front_queue.popleft()
        for neighbor in graph[node]:
            if neighbor in back_visited:  # 交汇
                return front_visited[node] + back_visited[neighbor] + 1
            if neighbor not in front_visited:
                front_visited[neighbor] = front_visited[node] + 1
                front_queue.append(neighbor)

        # 从后向前扩展
        node = back_queue.popleft()
        for neighbor in graph[node]:
            if neighbor in front_visited:  # 交汇
                return front_visited[neighbor] + back_visited[node] + 1
            if neighbor not in back_visited:
                back_visited[neighbor] = back_visited[node] + 1
                back_queue.append(neighbor)

    return -1  # 无法到达

# 示例图
graph = {
    0: [1, 2],
    1: [0, 3, 4],
    2: [0, 5],
    3: [1],
    4: [1],
    5: [2]
}
print(bidirectional_bfs(graph, 0, 5))  # 输出 2

适用条件起点到终点的最短路径搜索,可大幅减少搜索空间。


总结

BFS 版本适用场景
标准 BFS遍历整个图
单次 BFS 计算最短路径无权图最短路径(起点到所有点)
BFS 找最短路径(带路径回溯)具体的路径(非仅距离)
二维网格 BFS迷宫、地图、棋盘等问题
双向 BFS起点到终点最短路径,搜索空间大时更优

📌 如果只是遍历整个图,标准 BFS 就够用。
📌 如果要计算最短路径,就需要用 distance 数组或 path 记录路径。
📌 对于大规模搜索,可以考虑 双向 BFS,提高效率。 🚀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值