图的深度搜索和广度搜索代码

详细解释见代码注释。

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']

你可能感兴趣的:(图的深度搜索和广度搜索代码)