美文网首页我爱编程数据结构
数据结构(八):邻接表与邻接矩阵

数据结构(八):邻接表与邻接矩阵

作者: zhipingChen | 来源:发表于2018-10-16 11:28 被阅读11次

    邻接表和邻接矩阵是图的两种常用存储表示方式,用于记录图中任意两个顶点之间的连通关系,包括权值。

    对于图 G=(V, E) 而言,其中 V 表示顶点集合,E 表示边集合。

    对于无向图 graph,图的顶点集合和边集合如下:

    V = \{1,2,3,4,5\}
    E =\{(1,2),(1,3),(1,4),(2,3),(3,4),(3,5)\}

    graph

    对于有向图 digraph,图的顶点集合和边集合如下:

    V = \{1,2,3,4,5\}
    E =\{<1,2>,<1,3>,<1,4>,<2,3>,<3,1>,<3,5>,<4,3>\}

    digraph

    邻接表

    无向图 graph 表示

    graph_adjacency_list

    有向图 digraph 表示

    digraph_adjacency_list

    若采用邻接表表示,则需要申请 |V| 个列表,每个列表存储一个顶点出发的所有相邻顶点。如果图 G 为有向图,则 |V| 个列表存储的总顶点个数为 |E|;如果图 G 为无向图,则 |V| 个列表存储的总顶点个数为 2 |E|(暂不考虑自回路)。即邻接表方式的存储空间复杂度为 O(|V|+|E|)

    邻接矩阵

    无向图 graph 表示

    graph_adjacency_matrix

    有向图 digraph 表示

    digraph_adjacency_matrix

    若采用邻接矩阵表示,则需要申请空间大小为 |V|^2 的二维数组,在二位数组中保存每两个顶点之间的连通关系,则无论有向图或无向图,邻接矩阵方式的存储空间复杂度皆为 O(|V|^2)。若只记录图中顶点是否连通,不记录权值大小,则可以使用一个二进制位来表示二维数组的每个元素,并且根据无向图的特点可知,无向图的邻接矩阵沿对角线对称,所以可以选择记录一半邻接矩阵的形式来节省空间开销。

    两种存储结构对比

    根据邻接表和邻接矩阵的结构特性可知,当图为稀疏图、顶点较多,即图结构比较大时,更适宜选择邻接表作为存储结构。当图为稠密图、顶点较少时,或者不需要记录图中边的权值时,使用邻接矩阵作为存储结构较为合适。

    代码附录

    邻接表结构
    # graph node definition
    class Node(object):
        def __init__(self, index, weight, next = None):
            self.index = index
            self.weight = weight
            self.next = next
    
    # adjacency list definition
    class AdjacencyList(object):
        def __init__(self, number):
            self.number = number
            self.list = [None] * number
    
        # insert node
        def insert(self, origin, index, weight = 1):
            node = Node(index, weight, self.list[origin - 1])
            self.list[origin - 1] = node
    

    测试代码:

    if __name__ == '__main__':
        graph = AdjacencyList(5)
        graph.insert(1, 2)
        graph.insert(1, 3)
        graph.insert(1, 4)
        graph.insert(2, 3)
        graph.insert(3, 1)
        graph.insert(3, 5)
        graph.insert(4, 3)
        for i in range(graph.number):
            print('node', (i + 1), 'links:', end = ' ')
            node = graph.list[i]
            while node:
                print(node.index, end = ' ')
                node = node.next
            print()
    

    输出结果:

    node 1 links: 4 3 2 
    node 2 links: 3 
    node 3 links: 5 1 
    node 4 links: 3 
    node 5 links: 
    
    邻接矩阵结构
    # adjacency list definition
    class AdjacencyMatrix(object):
        def __init__(self, number):
            self.number = number
            self.list = [[None] * number for i in range(number)]
    
        # insert node
        def insert(self, origin, index, weight = 1):
            self.list[origin - 1][index - 1] = weight
    

    测试代码:

    if __name__ == '__main__':
        graph = AdjacencyMatrix(5)
        graph.insert(1, 2)
        graph.insert(1, 3)
        graph.insert(1, 4)
        graph.insert(2, 3)
        graph.insert(3, 1)
        graph.insert(3, 5)
        graph.insert(4, 3)
        for i in range(graph.number):
            print('node', (i + 1), 'links:', end = ' ')
            j = 0
            while j < graph.number:
                print(j + 1, end = ' ') if graph.list[i][j] else None
                j += 1
            print()
    

    输出结果:

    node 1 links: 2 3 4 
    node 2 links: 3 
    node 3 links: 1 5 
    node 4 links: 3 
    node 5 links: 
    

    相关文章

      网友评论

        本文标题:数据结构(八):邻接表与邻接矩阵

        本文链接:https://www.haomeiwen.com/subject/svxtzftx.html