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 寻找最短路径(带路径回溯)
适用于 无向图 / 有向图,求 从 start
到 end
的最短路径,并返回路径。
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
,提高效率。 🚀