学习Depth First Search和Breadth First Search
Here we learn DFS and BFS in python😂
define our graph
graph = {
'A' : ['B','C','D'],
'B' : ['A','E','F'],
'C' : ['A','D','F','G'],
'D' : ['A','C','G'],
'E' : ['B'],
'F' : ['B','C'],
'G' : ['C','D']
}
graph["A"]
['B', 'C', 'D']
Design DFS
or BFS
function and test it.
DFS
def DFS(start , graph):
stack=[]
visit=[]
stack.append(start)
visit.append(start)
while stack:
node = stack.pop()
nodes = graph[node]
for i in nodes:
if i not in visit:
stack.append(i)
visit.append(i)
print(node,end="\t")
# return visit is useless, because in the list the sort is undefined
pop print here?
tmp=[1,2,3,4]
node=tmp.pop()
pop didn't print here
tmp
[1, 2, 3]
Test and Visualization
DFS('A',graph)
A D G C F B E
blue node or bar : stack (visiting)
yellow node or bar : visit (visited)
BFS
def BFS(start , graph):
queue=[]
visit=[]
queue.append(start)
visit.append(start)
while queue:
node = queue.pop(0) #only difference here
nodes = graph[node]
for i in nodes:
if i not in visit:
queue.append(i)
visit.append(i)
print(node,end="\t")
# return visit
Test and Visualization
BFS("A",graph)
A B C D E F G
blue node or bar : queue (visiting)
yellow node or bar : visit (visited)
Summary
我们不妨定义 :与当前节点连接且访问过的节点称为父节点,与当前节点连接但未访问的节点称为子节点,同一个父节点的子节点互称兄弟节点
DFS和BFS比起来,两者在visiting变量中分别是用了栈和队列,
这样导致的最大不同就是在添加到visited变量(我们把它理解成一个栈)时,是考虑最先添加的节点(兄弟节点)还是考虑最后添加的节点(子节点),
注意:我们访问某个节点时做两件事情
1.知道它有哪些节点
2.选择下一步要访问的是子节点还是兄弟节点
BFS 优先考虑兄弟节点
若我们每次总是习惯考虑完先添加的节点,那我们就是倾向于一层一层的思考,即
把一层节点添加到visited后,回到最初节点,考虑该节点的子节点,再添加一层节点
再访问下一个兄弟节点,知道一下它的下一层的子节点,永远都是考虑还有没有另一条路
直到没有兄弟节点,回忆起最初添加的子节点这件事
直到结束
DFS 优先考虑子节点
若我们每次总是习惯考虑完后添加的节点,那我们就是倾向于深入的思考,即
把一层节点添加到visiting后,直接访问最后添加的那个节点,继续探索下一层的节点,这时一层只有一个节点visited
继续访问子节点的子节点,永远都是考虑路后面还有没有路
直到没有子节点,回忆起最近添加的兄弟节点
直到结束
例子:
这周布置了web开发和程序设计和数据结构和离散数学和数值分析和大学物理等等若干份作业:
BFS
还有多少科作业才做完啊,用广度形容很合适;
DFS
这科作业什么时候做得完啊,用深度形容很合适;
You can change the parameterstart
in DFS() or BFS() to understand the method of searching in the graph.
DFS("B",graph)
B F C G D E A
BFS("B",graph)
B A E F C D G