不同情况下的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,提高效率。

你可能感兴趣的:(算法,前端)