一. BFS(广度优先遍历)
1. 理解
概念:
BFS即广度优先遍历,BFS总是先访问完同一层的结点,然后才继续访问下一层结点,它最有用的性质是可以遍历一次就生成起始结点到所遍历结点的最短路径,这一点在求无权图的最短路径时非常有用。
遍历:
选择任意一个结点作为开始的结点,假如从A点出发:
可能的结果有:
A B C D E F
A C B D E F
A C B E D F
A B C E D F (❌)因为B没有和E相连,而且要求在遍历的时候先走哪一个就把那一个走完。
假如从E点出发:
E C D A B F
2. 类比
类比树有这种层序遍历的思想
3. 代码实现
需要借用一个队列来实现。
graph = {
"A": ["B", "C"],
"B": ["A", "C", "D"],
"C": ["A", "B", "D", "E"],
"D": ["B", "C", "E", "F"],
"E": ["C", "D"],
"F": ["D"]
}
# print(grap.keys())
# s代表开始的结点
def BFS(graph, s):
queue = []
queue.append(s)
seen = set() #定义一个集合
seen.add(s)
while len(queue)>0:
vertex = queue.pop(0)
nodes = graph[vertex]
for w in nodes:
if w not in seen:
queue.append(w)
seen.add(w)
print(vertex)
BFS(graph, 'A')
4. 扩展 无权图求最短路径
通过一次广度优先遍历之后,可以得到从起始点出发到某一点的最短路径。
graph = {
"A": ["B", "C"],
"B": ["A", "C", "D"],
"C": ["A", "B", "D", "E"],
"D": ["B", "C", "E", "F"],
"E": ["C", "D"],
"F": ["D"]
}
# s代表开始的结点
def BFS(graph, s):
queue = []
queue.append(s)
seen = set() #定义一个集合
seen.add(s)
parent = {s: None}
while len(queue)>0:
vertex = queue.pop(0)
nodes = graph[vertex]
for w in nodes:
if w not in seen:
queue.append(w)
seen.add(w)
parent[w] = vertex
print(vertex)
return parent
parent = BFS(graph, 'E')
print(parent)
v = 'B'
while v!= None:
print(v)
v = parent[v]
二. DFS(深度优先遍历)
1. 理解
从任意一点出发,一直走到底。
2. 代码实现:
需要借助一个栈来实现。
graph = {
"A": ["B", "C"],
"B": ["A", "C", "D"],
"C": ["A", "B", "D", "E"],
"D": ["B", "C", "E", "F"],
"E": ["C", "D"],
"F": ["D"]
}
# print(grap.keys())
# s代表开始的结点
def DFS(graph, s):
stack = []
stack.append(s)
seen = set() #定义一个集合
seen.add(s)
while len(stack)>0:
vertex = stack.pop()
nodes = graph[vertex]
for w in nodes:
if w not in seen:
stack.append(w)
seen.add(w)
print(vertex)
DFS(graph, 'A')
参考链接:https://www.bilibili.com/video/av25761720/?spm_id_from=333.788.videocard.1
参考链接:https://www.bilibili.com/video/av25763384/?spm_id_from=333.788.videocard.0