- 广度优先遍历(BFS)的特点
- 采用“横向搜索”策略:从起始顶点出发,先访问当前层的所有顶点,再逐层向外扩展,即优先访问距离起点更近的顶点。
- 借助队列实现先进先出(FIFO)机制:确保顶点按访问顺序依次处理,保证了层次性。
- 能够找到无权图中从源点到其他顶点的最短路径(边数最少)。
- 算法逻辑(基于邻接链表)
from collections import deque
def bfs(graph, start):
# graph: 邻接链表表示的图,如 {'A': ['B', 'C'], 'B': ['A', 'D'], ...}
visited = set() # 标记已访问顶点
queue = deque() # 创建队列
if start not in visited:
queue.append(start)
visited.add(start)
while queue:
vertex = queue.popleft() # 取出队头
print(vertex, end=' ') # 输出当前顶点
# 遍历该顶点的所有邻接顶点
for neighbor in graph[vertex]:
if neighbor not in visited:
visited.add(neighbor)
queue.append(neighbor)
# 示例使用:
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}
bfs(graph, 'A') # 输出:A B C D E F
- 算法复杂度与对比
- 时间复杂度:O(V + E),其中 V 是顶点数,E 是边数。每个顶点入队一次,每条边被检查一次。
- 空间复杂度:O(V),用于存储 visited 集合和队列。
- 与 DFS 对比:
- BFS 使用队列,DFS 使用栈(递归或显式栈);
- BFS 按层次访问,适合求最短路径;DFS 更深入,适合探索所有可能路径。
拓展:广度优先遍历的应用
- 无权图的单源最短路径问题(如迷宫最短路径)
- 树或图的层序遍历(如二叉树的层序遍历)
- 判断图的连通性(通过一次 BFS 是否访问所有顶点)
- 社交网络中的“朋友推荐”或“六度空间”问题
- 网络爬虫中控制爬取深度
使用广度优先搜索(BFS)实现二叉树的层序遍历,核心思想是按层次从上到下、从左到右访问每个节点。这与图的BFS一致,借助队列(FIFO)来保证访问顺序。
实现思路:
- 将根节点入队。
- 当队列不为空时:
- 出队一个节点并访问(输出或处理)。
- 将其左子节点和右子节点(若存在)依次入队。
- 重复直到队列为空。
Python代码实现:
from collections import deque
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def level_order_traversal(root):
if not root:
return []
result = [] # 存储遍历结果
queue = deque([root]) # 初始化队列,根节点入队
while queue:
node = queue.popleft() # 出队头节点
result.append(node.val)
# 左右子节点入队(如果存在)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return result
# 示例构建二叉树:
# 1
# / \
# 2 3
# / \
# 4 5
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
print(level_order_traversal(root)) # 输出: [1, 2, 3, 4, 5]
扩展:按层返回每一层的结果
如果需要每层作为一个子列表返回(如 [[1], [2,3], [4,5]]),可以稍作修改:
def level_order_by_level(root):
if not root:
return []
result = []
queue = deque([root])
while queue:
level_size = len(queue) # 当前层的节点数量
current_level = []
for _ in range(level_size):
node = queue.popleft()
current_level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(current_level)
return result
调用 level_order_by_level(root) 输出:[[1], [2, 3], [4, 5]]
时间与空间复杂度
- 时间复杂度:O(n),n 为节点数,每个节点入队出队一次。
- 空间复杂度:O(w),w 为树的最大宽度(队列中最多存储一层的节点)。


322

被折叠的 条评论
为什么被折叠?



