title: ‘图的遍历:BFS和DFS’
date: 2019-09-03 19:24:07
tags: python,数据结构
categories: 计算机理论
图的遍历
BFS(广度优先搜索)
算法原理及步骤
按照广度优先原则遍历图,利用了队列,有点像树的层次遍历。广度优先遍历的结果不唯一。整个遍历过程大概是这样的:给定一个起始顶点,将该起始顶点入队
- 顶点出队,如果当前顶点未被标记访问,则访问该顶点,然后标记为已访问,如果当前顶点已访问则直接丢弃该顶点
- 当前访问顶点的邻接顶点入队
- 当队列不为空的时候,循环1,2步
算法流程
算法实现
# 广度优先遍历
def bfs(self, start):
if not self._invalid(start):
raise GraphError("不存在" + start + "这样的顶点")
queue = [start] # 队列实现BFS
seen = set(start) # 记录访问过的顶点
parent = {start: None} # Node代表根节点,数组形式保存树
result = []
while queue.__len__() > 0: # 队非空时
vertex = queue.pop(0) # 队首顶点出队
nodes = self._graph[vertex] # 获得其邻接顶点
for node in nodes:
if node not in seen:
queue.append(node) # 其邻接顶点如果没有被访问,则入队,并且保留父顶点
seen.add(node)
parent[node] = vertex
result.append(vertex)
return result, parent
测试
例如遍历下图
具体的存储结构为:
data = {
"A": {"B": 5, "C": 1},
"B": {"A": 5, "C": 2, "D": 1},
"C": {"A": 1, "B": 2, "D": 4, "E": 8},
"D": {"B": 1, "C": 4, "E": 3, "F": 6},
"E": {"C": 8, "D": 3},
"F": {"D": 6},
}
def test_bfs(self):
print("bfs测试:")
bfs, bfsparent = TestGraph.g.bfs("A")
print("BFS:" + graph.GraphAL.printPath(bfs))
print("BFS生成路径:" + bfsparent.__str__())
print("BFS生成路径打印:" + graph.GraphAL.printTreePath(bfsparent).__str__())
pass
DFS(深度优先搜索)
算法原理及步骤
DFS和BFS很像,不过DFS是深度优先的原则,具体实现是栈。
DFS遍历的结果不唯一。整个遍历过程大概是这样的:给定一个起始顶点,将该起始顶点入栈
- 顶点出栈,如果当前顶点未被标记访问,则访问该顶点,然后标记为已访问,如果当前顶点已访问则直接丢弃该顶点
- 当前访问顶点的邻接顶点入栈
- 当栈不为空的时候,循环1,2步
算法实现
# 深度优先遍历
def dfs(self, start):
if not self._invalid(start):
raise GraphError("不存在" + start + "这样的顶点")
stack = [start] # 栈实现DFS
seen = set(start) # 记录访问过的顶点
parent = {start: None} # Node代表根节点,数组形式保存树
result = []
while stack.__len__() > 0: # 栈非空时
vertex = stack.pop() # 顶点出栈
nodes = self._graph[vertex] # 获取出栈顶点的邻接顶点
for node in nodes:
if node not in seen:
stack.append(node)
seen.add(node)
parent[node] = vertex
result.append(vertex)
return result, parent
测试
例如遍历下图
存储结构
data = {
"A": {
"B": 5, "C": 1},
"B": {
"A": 5, "C": 2, "D": 1},
"C": {
"A": 1, "B": 2, "D": 4, "E": 8},
"D": {
"B": 1, "C": 4, "E": 3, "F": 6},
"E": {
"C": 8, "D": 3},
"F": {
"D": 6},
}
测试结果
图的结构为:
('A', {'B': 5, 'C': 1})
('B', {'A': 5, 'C': 2, 'D': 1})
('C', {'A': 1, 'B': 2, 'D': 4, 'E': 8})
('D', {'B': 1, 'C': 4, 'E': 3, 'F': 6})
('E', {'C': 8, 'D': 3})
('F', {'D': 6})
dfs测试:
DFS:A->C->E->D->F->B
DFS生成路径:{'A': None, 'B': 'A', 'C': 'A', 'D': 'C', 'E': 'C', 'F': 'D'}
DFS生成路径打印:
A->B
A->C
A->C->D
A->C->E
A->C->D->F