图的遍历算法有深度优先搜索算法和广度优先搜索算法。
深度优先搜索属于图算法的一种,是一个针对图和树的遍历算法,英文缩写为DFS(Depth First Search)。深度优先搜索是图论中的经典算法,利用深度优先搜索算法可以产生目标图的相应拓扑排序表,利用拓扑排序表可以方便的解决很多相关的图论问题,如最大路径问题等等。一般用堆数据结构来辅助实现DFS算法。其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。
采用的数据结构是(正)邻接链表。
深度优先搜素遍历类似树的先序遍历,是树的先序遍历的推广。
算法思想::
设初始状态时图中的所有顶点未被访问,则:
(1):从图中某个定点Vi出发,访问Vi;然后找到Vi的一个邻接顶点Vi1;
(2):从Vi1出发,深度优先搜索访问和Vi1相邻接且未被访问的所有顶点;
(3):转(1),直到和Vi相邻接的所有顶点都被访问为止;
(4):继续选取图中未被访问顶点Vj作为起始顶点,转(1),直到图中所有顶点都被访问为止
算法代码:
#!/usr/bin/python
# -*- coding: utf-8 -*-
class Graph(object):
def __init__(self,*args,**kwargs):
self.node_neighbors = {}
self.visited = {}
def add_nodes(self,nodelist):
for node in nodelist:
self.add_node(node)
def add_node(self,node):
if not node in self.nodes():
self.node_neighbors[node] = []
def add_edge(self,edge):
u,v = edge
if(v not in self.node_neighbors[u]) and ( u not in self.node_neighbors[v]):
self.node_neighbors[u].append(v)
if(u!=v):
self.node_neighbors[v].append(u)
def nodes(self):
return self.node_neighbors.keys()
"""
#深度优先遍历函数
# Depth-First-Search
深度优先算法,是一种用于遍历或搜索树或图的算法。沿着树的深度遍历树的节点,尽可能深的搜索树的分支。
当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。
这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,
则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。属于盲目搜索。
"""
def depth_first_search(self,root=None):
order = []
def dfs(node):
self.visited[node] = True
order.append(node)
for n in self.node_neighbors[node]:
if not n in self.visited:
dfs(n)
if root:
dfs(root)
for node in self.nodes():
if not node in self.visited:
dfs(node)
print(order)
return order
if __name__ == '__main__':
g = Graph()
g.add_nodes([i+1 for i in range(9)])
g.add_edge((1, 2))
g.add_edge((1, 8))
g.add_edge((2, 3))
g.add_edge((2, 5))
g.add_edge((3, 4))
g.add_edge((4, 5))
g.add_edge((4, 6))
g.add_edge((6, 7))
g.add_edge((6, 8))
g.add_edge((8, 9))
print("nodes:", g.nodes())
order = g.depth_first_search(1)
#运行结果:1,2,3,4,5,6,7,8,9
广度优先搜索算法(Breadth First Search),又称为“宽度优先搜索”或“横向优先搜索”,简称BFS;BFS是用于图的查找算法。
BFS可用于解决2类问题:
算法思想:
从图中某顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使得“先被访问的顶点的邻接点先于后被访问的顶点的邻接点被访问,直至图中所有已被访问的顶点的邻接点都被访问到。如果此时图中尚有顶点未被访问,则需要另选一个未曾被访问过的顶点作为新的起始点,重复上述过程,直至图中所有顶点都被访问到为止。
#!/usr/bin/python
# -*- coding: utf-8 -*-
class Graph(object):
def __init__(self,*args,**kwargs):
self.node_neighbors = {}
self.visited = {}
def add_nodes(self,nodelist):
for node in nodelist:
self.add_node(node)
def add_node(self,node):
if not node in self.nodes():
self.node_neighbors[node] = []
def add_edge(self,edge):
u,v = edge
if(v not in self.node_neighbors[u]) and ( u not in self.node_neighbors[v]):
self.node_neighbors[u].append(v)
if(u!=v):
self.node_neighbors[v].append(u)
def nodes(self):
return self.node_neighbors.keys()
#广度优先遍历函数
def breadth_first_search(self,root=None):
queue = []
order = []
def bfs():
while len(queue)> 0:
node = queue.pop(0)
self.visited[node] = True
for n in self.node_neighbors[node]:
if (not n in self.visited) and (not n in queue):
queue.append(n)
order.append(n)
if root:
queue.append(root)
order.append(root)
bfs()
for node in self.nodes():
if not node in self.visited:
queue.append(node)
order.append(node)
bfs()
print(order)
return order
if __name__ == '__main__':
g = Graph()
g.add_nodes([i+1 for i in range(9)])
g.add_edge((1, 2))
g.add_edge((1, 8))
g.add_edge((2, 3))
g.add_edge((2, 5))
g.add_edge((3, 4))
g.add_edge((4, 5))
g.add_edge((4, 6))
g.add_edge((6, 7))
g.add_edge((6, 8))
g.add_edge((8, 9))
print("nodes:", g.nodes())
order = g.breadth_first_search(1)
#运行结果:1,2,8,3,5,6,4,7