详细解释见代码注释。
from collections import deque
class Graph(object):
def __init__(self):
self._graph = dict()
def add_node(self, node, *edge):
if node not in self._graph:
# 在犹豫使用set好还是list好
# 如果需要更改,那么只改这个位置和下一行代码即可,其他代码不需要更改也可正常运行
self._graph[node] = set()
self._graph[node].update(*edge)
def BFS(self, root):
"""
广度搜索
:param root: 从哪个点开始搜索
:return: 返回广度搜索的顺序
"""
# 使用队列来保存广度搜索的过程
search_queue = deque()
# 搜索结果顺序
bfs_sort = []
if root is None:
return None
# 首先需要把传入的节点广度搜索,之后再搜索其他无关联的点
self._BFS(bfs_sort, search_queue, root)
for node in self._graph:
self._BFS(bfs_sort, search_queue, node)
return bfs_sort
def _BFS(self, bfs_sort, search_queue, node):
search_queue.append(node)
# 判断队列是否为空
while search_queue:
# 从队列中取出数据,判断是否已经遍历过,如果遍历过
# 它以及它的邻居节点都遍历过,直接跳过
node = search_queue.popleft()
if node in bfs_sort:
continue
bfs_sort.append(node)
# 广度搜索,将它的子节点都加入搜索队列中
for n in self._graph[node]:
search_queue.append(n)
def DFS(self, root):
"""
深度搜索
:param root: 从哪个节点开始
:return: 搜索结果顺序
"""
if root is None:
return None
dfs_sort = []
# 使用栈(列表)来保存过程
stack = []
# 首先搜索传入的节点,在该节点以及它的邻居节点都搜索完毕后,再搜索跟它无关联的节点
self._DFS(dfs_sort, stack, root)
for node in self._graph:
self._DFS(dfs_sort, stack, node)
return dfs_sort
def _DFS(self, dfs_sort, stack, node):
stack.append(node)
# 判断过程栈是否为空
while stack:
# 先进后出
cur = stack.pop()
if cur not in dfs_sort:
dfs_sort.append(cur)
try:
# 深度搜索,把当前节点的下一个邻居节点加入,不要加入所有的邻居节点
# 使用了set(),避免报错,加上try,如果该节点没有邻居节点,那么continue即可
next_node = self._graph.get(cur, None).pop()
# if next_node is not None:
stack.append(next_node)
except:
continue
def print_graph(self):
print(self._graph)
def bfs(g):
b = g.BFS('A')
print('BFS---')
print(b)
def dfs(g):
d = g.DFS('A')
print('DFS---')
print(d)
def init_graph():
g = Graph()
# 第一个参数是节点,后面的参数是它的邻居节点
# 可传入多种类型,例如单个字符,多个字符,列表
g.add_node('B', 'H')
g.add_node('A', ['B'])
g.add_node('A', 'C')
g.add_node('D', ['C', 'F'])
g.add_node('C', 'E', 'D')
g.add_node('E', 'C', 'H')
g.add_node('G', 'H', 'F')
g.add_node('H', 'B', 'E', 'G')
g.add_node('F', 'D', 'G')
g.add_node('Z')
g.add_node('Y')
print('图---')
g.print_graph()
return g
if __name__ == '__main__':
g = init_graph()
bfs(g)
dfs(g)
输出结果:
图---
{'B': {'H'}, 'A': {'B', 'C'}, 'D': {'C', 'F'}, 'C': {'E', 'D'}, 'E': {'H', 'C'}, 'G': {'H', 'F'}, 'H': {'E', 'G', 'B'}, 'F': {'G', 'D'}, 'Z': set(), 'Y': set()}
BFS---
['A', 'B', 'C', 'H', 'E', 'D', 'G', 'F', 'Z', 'Y']
DFS---
['A', 'B', 'H', 'E', 'D', 'C', 'G', 'F', 'Z', 'Y']