今天来分享一下图论中最经典的两种遍历算法。
深度优先遍历DFS,广度优先遍历BFS。
讲述他们的原理,思想,与完美python代码。
深度优先遍历DFS
深度优先遍历:
- 寻找初始点,并将该点压入一个栈Q中。(这里采用python的内置容器的list)
- pop弹出Q栈的末尾元素,判断该元素是否被访问过。(这里我们采用一个set集合S,来实现判断是否访问的功能)
- 如果该元素被访问过,那么回到步骤2;否则进入步骤4.
- 访问该元素,并将该元素邻接的元素压入栈Q中。回到步骤2
- 当Q空栈的时候,结束程序。
首先,我们以下面的图作为我们的样例图。
搭建图的存储结构,一般可以使用邻接矩阵与邻接表
老卫喜欢邻接矩阵,所以构建该图的邻接矩阵。
[0,1,1,1,1,1,0,0],
[1,0,1,0,1,0,0,0],
[1,1,0,1,0,0,0,0],
[1,0,1,0,1,0,0,0],
[1,1,0,1,0,1,0,0],
[1,0,1,0,1,0,1,1],
[0,0,0,0,0,1,0,1],
[0,0,0,0,0,1,1,0]
python代码如下:
graph=[
[0,1,1,1,1,1,0,0],
[1,0,1,0,1,0,0,0],
[1,1,0,1,0,0,0,0],
[1,0,1,0,1,0,0,0],
[1,1,0,1,0,1,0,0],
[1,0,1,0,1,0,1,1],
[0,0,0,0,0,1,0,1],
[0,0,0,0,0,1,1,0]
]
def Dfs(G,start):
S,Q=set(),list()
Q.append(start)
result=[]
while(Q):
u=Q.pop()
if (u in S):
continue
S.add(u)
for i in range(len(G)):
if(G[u][i]==1):
Q.append(i)
result.append(u)
return result
print(Dfs(graph,0))
广度优先遍历BFS
广度优先遍历:
- 寻找初始点,并将该点压入一个队列Q中。(这里采用python的容器库collections的deque)
- 将队列的首元素弹出,判断该元素是否被访问过。(这里我们采用一个set集合Q,来实现判断是否访问的功能)
- 如果该元素被访问过,那么回到步骤2;否则进入步骤4.
- 访问该元素,并将该元素邻接的元素压入队列Q中。回到步骤2
- 当Q空队列的时候,结束程序。
我们还是以上面的图为例:
python代码如下:
from collections import deque
graph=[
[0,1,1,1,1,1,0,0],
[1,0,1,0,1,0,0,0],
[1,1,0,1,0,0,0,0],
[1,0,1,0,1,0,0,0],
[1,1,0,1,0,1,0,0],
[1,0,1,0,1,0,1,1],
[0,0,0,0,0,1,0,1],
[0,0,0,0,0,1,1,0]
]
def bfs(G,s):
S,Q=set(),deque([s])
result=[]
while(Q):
u=Q.popleft()
if(u in S):
continue
S.add(u)
for v in range(len(G)):
if(G[u][v]==1):
Q.append(v)
result.append(u)
return result
print(bfs(graph,0))