BFS 和 DFS(深度优先搜索、广度优先搜索)
创作时间:
作者:
@小白创作中心
BFS 和 DFS(深度优先搜索、广度优先搜索)
引用
CSDN
1.
https://blog.csdn.net/weixin_47520540/article/details/145800093
深度优先搜索(DFS)和广度优先搜索(BFS)是两种常用的图遍历算法,用于解决图相关的问题。它们在搜索问题中具有广泛的应用,如路径搜索、连通性检测等。
图片引自:https://www.cnblogs.com/xuxinstyle/p/13261651.html
深度优先搜索(DFS)
深度优先搜索是一种先探索到尽可能深的节点,再回溯到之前的节点的搜索策略。在实现上,DFS通常使用递归或栈来实现。
模板:
def dfs(node, visited):
if node in visited:
return
visited.add(node)
# Process current node
# Explore neighbors
for neighbor in node.neighbors:
dfs(neighbor, visited)
讲解:
- 从起始节点开始,访问当前节点并标记为已访问。
- 对当前节点的邻居节点进行遍历,若邻居节点未被访问过,则以该邻居节点为新的当前节点,继续进行深度优先搜索。
- 递归地进行上述步骤,直到所有可达节点都被访问。
例题:
问题:给定一个无向图,判断是否存在从节点A到节点B的路径。
def hasPath(graph, start, end):
"""
判断是否存在从start到end的路径
Args:
graph: 图的邻接表表示
start: 起始节点
end: 目标节点
Returns:
bool: 如果存在路径返回True,否则返回False
"""
visited = set()
return dfs(start, end, visited, graph)
def dfs(node, end, visited, graph):
"""
深度优先搜索的辅助函数
Args:
node: 当前节点
end: 目标节点
visited: 已访问过的节点集合
graph: 图的邻接表表示
Returns:
bool: 如果存在路径返回True,否则返回False
"""
if node == end:
return True
visited.add(node)
for neighbor in graph[node]:
if neighbor not in visited:
if dfs(neighbor, end, visited, graph):
return True
return False
广度优先搜索(BFS)
广度优先搜索是一种先探索到当前节点的所有邻居节点,再逐层向外搜索的策略。通常使用队列来实现。
模板:
from collections import deque
def bfs(start):
"""
广度优先搜索
Args:
start: 起始节点
Returns:
None
"""
queue = deque([start])
visited = set()
while queue:
node = queue.popleft()
if node not in visited:
visited.add(node)
# Process current node
# 处理当前节点
# Explore neighbors
# 探索当前节点的邻居节点
for neighbor in node.neighbors:
queue.append(neighbor)
要点:
- 将起始节点加入队列,并标记为已访问。
- 当队列不为空时,弹出队首节点,对其未被访问的邻居节点进行遍历。
- 将未被访问的邻居节点加入队列,并标记为已访问。
- 重复上述步骤,直到队列为空。
分类模板:如果不需要确定当前遍历到了哪一层,模板如下
while queue 不空:
cur = queue.pop()
for 节点 in cur的所有相邻节点:
if 该节点有效且未访问过:
queue.push(该节点)
如果要确定当前遍历到了哪一层,BFS模板如下
这里增加了level表示当前遍历到二叉树中的哪一层了,也可以理解为在一个图中,现在已经走了多少步了。size表示在当前遍历层有多少个元素,也就是队列中的元素数,我们把这些元素一次性遍历完,即把当前层的所有元素都向外走了一步。
level = 0
while queue 不空:
size = queue.size()
while (size --) {
cur = queue.pop()
for 节点 in cur的所有相邻节点:
if 该节点有效且未被访问过:
queue.push(该节点)
}
level ++;
例题:
问题:给定一个无向图,从节点A开始,找到到节点B的最短路径的长度。
from collections import deque
def shortestPath(graph, start, end):
"""
寻找从start到end的最短路径长度
Args:
graph: 图的邻接表表示
start: 起始节点
end: 目标节点
Returns:
int: 最短路径长度,如果不存在路径则返回-1
"""
queue = deque([(start, 0)])
visited = set()
while queue:
node, distance = queue.popleft()
if node == end:
return distance
visited.add(node)
for neighbor in graph[node]:
if neighbor not in visited:
queue.append((neighbor, distance + 1))
return -1 # If no path found
# Example graph representation: {node: [neighbors]}
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}
print(shortestPath(graph, 'A', 'F')) # Output: 2
这里使用了BFS算法来搜索从节点A到节点B的最短路径的长度。
下面是代码的一些区别:这里使用字典来存图
BFS实现
#BFS实现
graph = {
"A":["B","C"],
"B":["A","C","D"],
"C":["A","B","D","F"],
"D":["B","C","E","F"],
"E":["C","D"],
"F":["D"]
}
def BFS(graph,s):
queue = []
queue.append(s)#将元素 s 加入到队列的尾部(队尾)
seen = set()#储存出现过的量
seen.add(s)
while(len(queue)>0):
vertex = queue.pop(0)#从队列的头部(队首)弹出元素
nodes = graph[vertex]#vertex的所有临接点
for w in nodes:
if w not in seen:
queue.append(w)
seen.add(w)
print(vertex)
BFS(graph,"A")
DFS实现 队列—>栈
graph = {
"A":["B","C"],
"B":["A","C","D"],
"C":["A","B","D","F"],
"D":["B","C","E","F"],
"E":["C","D"],
"F":["D"]
}
def BFS(graph,s):
queue = []
queue.append(s)
seen = set()#储存出现过的量
seen.add(s)
while(len(queue)>0):
vertex = queue.pop()#pop(0)->pop() 先弹出最后一个元素 这里体现出栈
nodes = graph[vertex]#vertex的所有临接点
for w in nodes:
if w not in seen:
queue.append(w)
seen.add(w)
print(vertex)
BFS(graph,"A")
热门推荐
有一种头痛,叫枕神经痛!可以这样诊断和治疗
签工作合同发朋友圈?这份法律指南请收好
必看 | 离焦软镜的验配流程指南
“一米高度”看城市,南京加快儿童友好公园建设
深入探讨体温调节研究:人体恒温机制的奥秘与科学进展
8种最有效的减肥运动,轻松减重无难度!
小肠寒怎样调理
四位选调生扎根基层,为乡村基础设施建设添砖加瓦
卷柏养护知识详解(卷柏是否有毒?能否放室内养?)
空气压缩机工作原理、维护保养及智能化发展趋势
从范进中举谈“暴喜伤心”
王珊珊:扎根雪域高原的格桑花
高压线安全距离的标准及重要性
11万伏高压线离住宅的安全距离 为什么要合理设计高压线距离
项目经理如何提高文笔
煎鱼时,别再拍粉或撒盐了,教你2招,鱼肉鲜嫩完整,不破皮不粘锅
俄制苏-35:美F-16不敢在战场1对1单挑,我国曾引进24架,作用大吗?
学诚法师:佛教戒律是实现成功人生的方便之路
2025年浙江新高考英语读后续写的评分标准与范文
贾母选择媳妇的四大标准:不求门当户对,但求重振祖业
半导体国产化加速,科创芯片ETF近1周规模增长28.47亿元
曹操《观沧海》和普希金《致大海》意象的比较
《致大海》:普希金的浪漫主义经典
女生喝啤酒有什么好处和坏处
【MATLAB M_map标签与注释】:让地图信息清晰易懂的策略
彼得·林奇的投资智慧:三种策略助你成功
一种淡水鱼循环水养殖系统及方法
南岳区十大特色美食,每一道都凝聚着当地的历史味道
预防胃痉挛的实用方法
考研复试必会的10种类型问题回答,一文尽览!