图遍历(DFS, BFS) python实现

一 摘要

图遍历方法包括深度遍历(DFS)和广度遍历(BFS)。图一般用邻接矩阵或者邻接表来储存,本实现代码中 采用词典来存储,相比于邻接矩阵,词典方式来存储会导致访问并没有那么快,因为需要遍历key对应的list才可以找到想要的边。
另外,无论是dfs还是bfs其实跟树遍历(因为树也是一种图,无环图)一样,用到的辅助数据结构都是queue(BFS)或者stack(DFS)

二 实现代码

import networkx as nx
import matplotlib.pyplot as plt


class GraphTraverser(object):
    """图遍历器,基于networks展示图
    """
    def __init__(self):
        return

    def gen_graph(self, node_list=[], edge_list=[()]):
        """生成图, 返回一个图词典,用来存储图
        :param node_list:
        :param edge_list:
        :return:
        """
        graph = nx.MultiDiGraph()
        graph.add_nodes_from(node_list)
        graph.add_edges_from(edge_list)
        nx.draw(graph, with_labels=True)
        plt.show()
        graph_dict = {}
        for node in node_list:
            graph_dict[node] = [next_node[1] for next_node in edge_list if next_node[0] == node]
        return graph_dict

    def bfs_traverse(self, graph, start_node):
        """广度优先遍历, 队列实现 fifo
        :param graph:
        :param start_node:
        :return:
        """
        queue = [start_node]
        visited = set()  # 看是否访问过该结点
        visited.add(start_node)
        while len(queue) > 0:
            vertex = queue.pop(0)  # 保存第一结点,并弹出,方便把他下面的子节点接入
            nodes = graph[vertex]  # 子节点的数组
            for next_node in nodes:
                if next_node not in visited:  # 判断是否访问过
                    queue.append(next_node)
                    visited.add(next_node)
            print(vertex)

    def dfs_traverse(self, graph, start_node):
        """深度优先访问 栈实现 filo, 回溯
        :param graph:
        :param start_node:
        :return:
        """
        stack = [start_node]
        visited = set()  # 看是否访问过
        visited.add(start_node)
        while len(stack) > 0:
            # 拿出邻接点
            vertex = stack.pop()  # 这里pop参数没有0了,最后一个元素
            nodes = graph[vertex]
            for next_node in nodes:
                if next_node not in visited:  # 如何判断是否访问过,使用一个数组
                    stack.append(next_node)
                    visited.add(next_node)
            print(vertex)


if __name__ == "__main__":
    graph = GraphTraverser()
    graph_dict = graph.gen_graph([1, 2, 3, 4, 5], [(1, 2), (1, 3), (1, 4), (2, 3), (3, 5)])
    print(graph_dict)
    graph.bfs_traverse(graph_dict, 1)
    print()
    graph.dfs_traverse(graph_dict, 1)

结果
有图如下
在这里插入图片描述
bfs与dfs结果:

1
2
3
4
5

1
4
3
5
2

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值