dfs bfs
深度优先搜索(DFS)和广度优先搜索(BFS)是图和树遍历中的重要算法,二者在实现方式和应用场景上存在明显差异。
- 定义与概念:DFS在遍历树或图时,以深度优先,从起始节点出发,尽可能深入地探索分支,直至无法继续,再回溯;BFS则按层次逐层遍历,从起始节点开始,先访问其所有邻接节点,再进入下一层。
- 代码实现
- DFS递归写法:借助递归函数,通过
visited
集合记录已访问节点,防止重复访问。对当前节点处理后,递归调用自身处理其未访问的子节点。 - DFS非递归写法:利用栈数据结构,将起始节点压入栈,循环从栈中弹出节点,处理并标记为访问过,再把相关节点压入栈。
- BFS写法:使用队列,将起始节点加入队列,循环从队列中取出节点,处理并标记,然后把其相关节点加入队列。
- DFS递归写法:借助递归函数,通过
- 遍历顺序差异:以二叉树为例,DFS按根节点、左子树、右子树顺序遍历,若有多个子节点,逐个深入;BFS按层次从左到右访问节点,先访问完一层,再进入下一层。
- 实战应用:在力扣题目中,二叉树的层次遍历可使用DFS递归或BFS实现。DFS递归通过记录节点层次添加到对应列表;BFS借助队列,逐层处理节点,将同一层节点值收集到列表。最小基因变化问题,可通过BFS搜索基因库,寻找从起始基因到目标基因的最少变化次数,每次变化生成新基因并判断是否在基因库及是否为目标基因。岛屿数量问题,用DFS遍历二维网格,将陆地标记为已访问,通过递归检查相邻陆地,统计岛屿数量。
深度优先搜索(DFS)
- 递归写法
visited = set()
def dfs(node):
if node in visited:
return
visited.add(node)
# 在这里处理当前节点,例如打印节点的值
print(node.val)
# 假设node有获取子节点的方法children()
for next_node in node.children():
if next_node not in visited:
dfs(next_node)
- 非递归写法
def dfs_non_recursive(root):
if not root:
return []
visited, stack = [], [root]
while stack:
node = stack.pop()
if node not in visited:
visited.append(node)
# 在这里处理当前节点,例如打印节点的值
print(node.val)
# 假设node有获取子节点的方法children()
stack.extend([child for child in node.children() if child not in visited][::-1])
return visited
广度优先搜索(BFS)
from collections import deque
def bfs(root):
if not root:
return []
visited, queue = [], deque([root]