python实现图的广度优先遍历和深度优先遍历

图的存储

图的存储分为邻接矩阵和邻接表,其中对于稀疏图邻接表的存储效率更高,对于稠密图邻接矩阵存储效率跟高。这里的BFS和DFS是基于邻接表实现,所以有关邻接矩阵的存储可以查阅百度百科
邻接点主要包括两部分:顶点和邻接点,顶点包括顶点信息和指向第一个邻接点的指针(python中使用元组模拟)。邻接点包括邻接点的存储下标和指向下一节点的指针。(python中使用列表模拟),顶点 V i V_i Vi的所有邻接点构成一个列表。

  • 目前电脑还没找到比较合适的画图工具,只能手机拍照了。
    在这里插入图片描述

图的遍历

广度优先搜索,又称宽度优先搜索。广度优先搜索是从某个顶点(源点)出发,一次性访问所有未被访问的邻接点,再依次从这些访问过的邻接点出发进行搜索。

  • 广度优先遍历秘籍:先被访问的顶点,其邻接点先被访问。采用队列的形式实现

深度优先搜索沿着一条路径一直走下去,无法行进时,回退到刚刚访问的节点。深度优先遍历是按照深度优先搜索的方式对图进行遍历。

  • 深度优先遍历秘籍:后被访问的顶点,其邻接点先被访问。采用递归的方式实现。

python实现

# coding=utf-8
from queue import Queue

# Definition for a Node.
class Node:
    def __init__(self, val):
        self.val = val
        self.next = None

class Solution(object):
    """
    根据邻接表创建有向图
    """
    def __init__(self,adj_list):
        self.adj_list = adj_list
        self.peaks = []
        self.visited = [False]*len(self.adj_list)
    def bfs(self):
        """
        广度优先遍历,时间复杂度O(n)
        :return:
        """
        
        queue = Queue()
        self.visited = [False]*len(self.adj_list) # 存储顶点的访问状态
        queue.put(0) # 默认从邻接表第0个邻接点开始
        self.visited[0] = True
        self.peaks = self.adj_list[0][0]
        while not queue.empty():
            index = queue.get() # 出队
            for i in self.adj_list[index][1]:
                if not self.visited[i]: # 判断是否被访问
                    self.visited[i] = True
                    queue.put(i) # 入队
                    self.peaks.append(adj_list[i][0])
            print(self.visited)
        return self.peaks
    
    def dfs(self,node):
        """
        递归调用深度优先遍历,时间复杂度O(n)
        :return:
        """
        self.visited[node] = True
        self.peaks.append(self.adj_list[node][0])
        for index in self.adj_list[node][1]:
            # 判断该节点是否被访问过
            if not self.visited[index]:
                self.dfs(index)
            # print(index)
        return self.peaks
if __name__ == '__main__':
    # 邻接表表示有向图
    adj_list = [
        ("a",[4,2,1]),
        ("b",[2]),
        ("c",[4,3]),
        ("d",[4]),
        ("e",[]),
        ]
    solution = Solution(adj_list)
    # print(solution.bfs())
    print(solution.dfs(0))
    ```

  • 0
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 以下是广度优先遍历深度优先遍历Python实现代码: ```python # 广度优先遍历 def bfs(graph, start): visited = set() # 已访问过的节点集合 queue = [start] # 初始化队列 while queue: node = queue.pop(0) # 取出队首节点 if node not in visited: visited.add(node) print(node, end=' ') for neighbor in graph[node]: if neighbor not in visited: queue.append(neighbor) # 深度优先遍历 def dfs(graph, start, visited=None): if visited is None: visited = set() # 已访问过的节点集合 visited.add(start) print(start, end=' ') for neighbor in graph[start]: if neighbor not in visited: dfs(graph, neighbor, visited) # 示例 graph = { 'A': ['B', 'C'], 'B': ['A', 'D', 'E'], 'C': ['A', 'F'], 'D': ['B'], 'E': ['B', 'F'], 'F': ['C', 'E'] } # 广度优先遍历 print('BFS:', end=' ') bfs(graph, 'A') print() # 深度优先遍历 print('DFS:', end=' ') dfs(graph, 'A') print() ``` 输出结果: ``` BFS: A B C D E F DFS: A B D E F C ``` 其中,`graph`是一个字典类型的表示,键为节点,值为与该节点相邻的节点列表。`start`为遍历的起点节点。 ### 回答2: 广度优先遍历(BFS)和深度优先遍历(DFS)是两种常用的遍历算法,下面是它们的代码实现广度优先遍历代码实现(BFS): ``` def BFS(graph, start): visited = set() # 记录已访问过的节点 queue = [] # 使用队列来辅助实现BFS visited.add(start) queue.append(start) while queue: node = queue.pop(0) # 弹出队首节点 print(node, end=" ") # 访问节点 for neighbor in graph[node]: if neighbor not in visited: visited.add(neighbor) queue.append(neighbor) ``` 深度优先遍历代码实现(DFS): ``` def DFS(graph, start, visited): visited.add(start) print(start, end=" ") # 访问节点 for neighbor in graph[start]: if neighbor not in visited: DFS(graph, neighbor, visited) ``` 在以上两种代码中,`graph`是的表示方式,通常使用邻接表或邻接矩阵来表示;`start`是起始节点;`visited`是记录已访问节点的集合。 广度优先遍历使用队列来辅助遍历,从起始节点开始,将其加入队列并标记为已访问,然后从队列中弹出一个节点,访问它,并将其未访问过的邻居加入队列;一直重复这个过程,直到队列为空。 深度优先遍历使用递归方式实现,从起始节点开始,首先将其标记为已访问,然后递归地访问它的邻居节点,直到没有未访问的邻居节点为止,然后回溯到上一级节点,继续递归访问其未访问的邻居节点。这样一直递归下去,直到遍历完整个。 BFS和DFS都可以遍历的所有节点,并且每个节点仅被访问一次。 ### 回答3: 广度优先遍历(BFS)和深度优先遍历(DFS)是常用的遍历算法。以下是它们的代码实现广度优先遍历(BFS): 1. 建立一个队列,并将起始节点加入队列; 2. 创建一个visited列表,用于记录已经遍历过的节点; 3. 循环队列,直到队列为空: - 从队列中弹出一个节点,并将其标记为visited; - 遍历该节点的所有相邻节点: - 如果相邻节点未被visited,则将其加入队列; 4. 返回visited列表,即为广度优先遍历的结果。 下面是使用Python实现广度优先遍历代码: ``` def bfs(graph, start): visited = [] queue = [start] while queue: node = queue.pop(0) if node not in visited: visited.append(node) neighbors = graph[node] for neighbor in neighbors: queue.append(neighbor) return visited ``` 深度优先遍历(DFS): 1. 创建一个visited列表,用于记录已经遍历过的节点; 2. 定义一个递归函数,用于进行深度优先遍历: - 将当前节点标记为visited; - 遍历当前节点的所有相邻节点: - 如果相邻节点未被visited,则递归调用该函数; 3. 在主函数中调用递归函数,并返回visited列表,即为深度优先遍历的结果。 下面是使用Python实现深度优先遍历代码: ``` def dfs(graph, start, visited): visited.append(start) neighbors = graph[start] for neighbor in neighbors: if neighbor not in visited: dfs(graph, neighbor, visited) def dfsTraversal(graph, start): visited = [] dfs(graph, start, visited) return visited ``` 需要注意的是,上述代码中的graph是以字典形式表示的,其中键表示节点,值表示与该节点相邻的节点列表。此外,代码还需要预先定义起始节点start。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值