首页 文章详情

Python算法-图的遍历算法(1)

等风来也等你 | 83 2024-06-03 06:42 0 0 0
UniSMS (合一短信)

e34e8b176a79478ff775ac29680677b1.webp

491d4df5e0f36b30a34e53962f747d57.webp 图的遍历是指从图中的某个顶点(该 顶点 可称为起始点 )出发,按照 某个 特定 方式访问图中的各个顶点,使每个可访问到的顶点都被访问一次。图 遍历 方式有两种, 一种 是深度优先遍历 (也 叫作深度优先搜索 ,简称 DFS ,还有一种是广度优先遍历 (也叫做 广度优先搜索 简称为 BFS 说明: 起始点可以 任意指定, 起始点 不同得到的 遍历 序列也不 相同。 注意: 在遍历 时,每个顶点只能访问一次, 不可 重复访问。

深度优先 遍历 算法

深度优先遍历算法 是经典的图论算法。 思想 :从一条路径的起始点开始追溯,直到到达路径 最后一个顶点,然后回溯,继续追溯下一条路径,直到到达最后的顶点,如此往复,直到没有路径为止。它 的遍历过程如下: 1)以 图中的任一顶点 v 为出发点, 首先访问顶点 v ,并 将其标记为已被访问。 2)从顶点v的任一个邻接点出发 继续 进行 深度优先的搜索 ,直至图中所有和顶点v连通的顶点都已被访问。 3)若此时图中仍有未被访问的顶点,则选择一个未被访问的顶点作为新的出发点重复上述过程,直至图中所有顶点都已被访问为止。 这种 图的 遍历 方法应用了堆栈这种数据结构的特点。下面 12. 4 所示 无向图 为例来介绍 这个 方法的遍历过程。

24c8975cc0db07805e5ed6afe7098816.webp

 

12 . 4   无向图

第一步 假设 以顶点 A 起点,将顶点 A压入 堆栈 如图 12. 5所示。

c4b33e9465d9f5b728539bb812658378.webp

          图12 . 5   堆栈图1                        12 . 6   堆栈图 2

第二步 弹出 顶点 A ,将 顶点A的邻接点 B C 压入 堆栈 如图 12. 6所示。 第三步 根据堆栈“后进先出”的 原则, 弹出 顶点C,将 与顶点 C 相邻 并且未 访问过的顶点B 顶点 D 顶点 E压入 堆栈 如图 12. 7所示。

a5ad6f5776f3d3983c58c84d232e6851.webp

          图12 . 7   堆栈图3                           12 . 8   堆栈图 4

第四步 弹出 顶点E,将 与顶点 E 相邻 并且未 访问过的顶点D 压入 堆栈 如图 12. 8所示。 第五步 弹出 顶点D,将 与顶点 D 相邻 并且未 访问过的顶点B 顶点 F压入 堆栈 如图 12. 9所示。

1a2acda8a76d3a5c69962b04fac4f286.webp

          图12 . 9   堆栈图 5             12 . 10   堆栈图 6

第六步 弹出 顶点F,将 与顶点 F 相邻 并且未 访问过的顶点 压入 堆栈 由于 顶点F 邻接点 D 已被访问过,所以无须压入堆栈 如图 12. 10所示。 第七步 弹出 顶点B,将 与顶点 B 相邻 并且未 访问过的顶点 压入 堆栈 由于 顶点 B 邻接点 已被访问过,所以无须压入堆栈 如图 12. 11所示。

34e26b3411df1a24903789697581f8f0.webp

         图12 . 11   堆栈图 7             12 . 12   堆栈图 8

第八步 将堆栈 中的 顶点 依次弹出,并判断是否已经访问过,直到 堆栈 中无顶点可以访问为止 如图 12. 12所示。 由此可知 ,对图 12. 4 的图 进行深度 优先遍历 顺序为: 顶点A、顶点 C 、顶点 E 、顶点 D 、顶点 F 、顶点 B 例中应用的深度优先函数的算法如下:


                
                  
                    01  def dfs(graph, start):
                  
                
                
                  
                    02      stack = []                              #定义堆栈
                  
                
                
                  
                    03      stack.append(start)                     #将起始顶点压入堆栈
                  
                
                
                  
                    04      visited = set()                         #定义集合
                  
                
                
                  
                    05      while stack:
                  
                
                
                  
                    06          vertex = stack.pop()                #弹出栈顶元素
                  
                
                
                  
                    07          if vertex not in visited:           #如果该顶点未被访问过
                  
                
                
                  
                    08              visited.add(vertex)             #将该顶点放入已访问集合
                  
                
                
                  
                    09              print(vertex,end = ' ')         #打印深度优先遍历的顶点
                  
                
                
                  
                    10          for w in graph[vertex]:             #遍历相邻的顶点
                  
                
                
                  
                    11              if w not in visited:            #如果该顶点未被访问过
                  
                
                
                  
                    12                  stack.append(w)             #把顶点压入堆栈
                  
                
              


下面在 实例中 应用Python代码来实现图的 深度优先遍历 有一个 无向图 如图12. 13所示 。以 顶点 A为出发点 对该图 进行深度优先遍历

2f9bcd5a8dde1a6eb928201ef5df99f2.webp

 

12 . 13   无向图

代码如下:


                
                  
                    01  graph = {                                   #定义图的字典
                  
                
                
                  
                    13      "A": ["B","C"],
                  
                
                
                  
                    14      "B": ["A","D","E"],
                  
                
                
                  
                    15      "C": ["A","D","G"],
                  
                
                
                  
                    16      "D": ["B","C","F","H"],
                  
                
                
                  
                    17      "E": ["B","F"],
                  
                
                
                  
                    18      "F": ["D","E","G","H"],
                  
                
                
                  
                    19      "G": ["C","F","H"],
                  
                
                
                  
                    20      "H": ["D","F","G"],
                  
                
                
                  
                    21  }
                  
                
                
                  
                    22  def dfs(graph, start):
                  
                
                
                  
                    23      stack = []                              #定义堆栈
                  
                
                
                  
                    24      stack.append(start)                     #将起始顶点压入堆栈
                  
                
                
                  
                    25      visited = set()                         #定义集合
                  
                
                
                  
                    26      while stack:
                  
                
                
                  
                    27          vertex = stack.pop()                #弹出栈顶元素
                  
                
                
                  
                    28          if vertex not in visited:           #如果该顶点未被访问过
                  
                
                
                  
                    29              visited.add(vertex)             #将该顶点放入已访问集合
                  
                
                
                  
                    30              print(vertex,end = ' ')         #打印深度优先遍历的顶点
                  
                
                
                  
                    31          for w in graph[vertex]:             #遍历相邻的顶点
                  
                
                
                  
                    32              if w not in visited:            #如果该顶点未被访问过
                  
                
                
                  
                    33                  stack.append(w)             #把顶点压入堆栈
                  
                
                
                  
                    34  print("图中各顶点的邻接点:")
                  
                
                
                  
                    35  for key,value in graph.items():             #遍历图的字典
                  
                
                
                  
                    36      print("顶点",key,"=>",end=" ")          #打印顶点
                  
                
                
                  
                    37      for v in value:                         #遍历顶点的邻接点
                  
                
                
                  
                    38          print(v,end=" ")                    #打印顶点的邻接点
                  
                
                
                  
                    39      print()
                  
                
                
                  
                    40  print("深度优先遍历的顶点:")
                  
                
                
                  
                    41  dfs(graph,"A")                              #调用函数并设置起点为A
                  
                
              


最终运行的结果如图1 2 . 14 所示。

45418d3e7a1587887e1f03431ec324ef.webp

 

1 2 . 14   打印深度 优先遍历序列


46596d129dc00a30d2763f9f5e25f728.webp

good-icon 0
favorite-icon 0
收藏
回复数量: 0
    暂无评论~~
    Ctrl+Enter