十一、图的存储---(2)邻接矩阵和邻接表

摘自计蒜客:http://www.jisuanke.com/course/35/7191

两个常见的图的存储结构——邻接矩阵和邻接表。

什么是邻接矩阵呢?所谓邻接矩阵存储结构就是用一维数组存储图中顶点的信息,用矩阵表示图中各顶点之间的邻接关系。

对于有 nn 个顶点的图 G = (V, E)G=(V,E) 来说,我们可以用一个 n * nn∗n 的矩阵 AA 来表示 GG 中各顶点的相邻关系,如果 v{i}和 v{j}之间存在边(或弧),则 A[i][j] = 1,否则 A[i][j] = 0。下图为有向图 G{1}以及对应的邻接矩阵。

十一、图的存储---(2)邻接矩阵和邻接表_第1张图片

下图为无向图 G{2}以及对应的邻接矩阵

十一、图的存储---(2)邻接矩阵和邻接表_第2张图片

图的邻接矩阵是唯一的,矩阵的大小只与顶点个数 N 有关,是一个 N * N 的矩阵。前面我们已经介绍过,在无向图里,如果顶点 v{i}和 v{j}之间有边,则可认为顶点 v{i}到 v{j}有边,同时顶点 v{j}到 v{i}也有边。对应到邻接矩阵里,则有 A[i][j] = A[j][i] = 1。因此我们可以发现,无向图的邻接矩阵是一个对称矩阵。


我们以图G1为例,演示下如何利用邻接矩阵计算顶点的入度和出度。顶点的出度,即为邻接矩阵上点对应行上所有值的总和,比如顶点 1对应的出度即为0+1+1+1=3;而每个点的入度即为点对应列上所有值的总和,比如顶点 3 对应的入度即为 1 + 0 + 0 + 1 = 2。

十一、图的存储---(2)邻接矩阵和邻接表_第3张图片


邻接表是图的一种顺序存储与链式存储相结合的存储方法。我们给图 GG 中的每个顶点建立一个单链表,第 ii 个单链表中的结点表示依附于顶点vi的边(对于有向图是以 vi为起点的弧)。所有单链表的表头结点都存储在一个一维数组中,以便于顶点的访问。下图为图 G1 对应的邻接表。

十一、图的存储---(2)邻接矩阵和邻接表_第4张图片十一、图的存储---(2)邻接矩阵和邻接表_第5张图片

在无向图的邻接表中,顶点vi的度为第 ii 个单链表中的结点数;而在有向图中,第 ii 个单链表中的结点数表示的是顶点i的出度,如果要求入度,则要遍历整个邻接表。
另外,在邻接表中,我们很容易就能知道某一顶点和哪些顶点相连接。


那我们什么时候用邻接矩阵,什么时候用邻接表呢?
可以看到,邻接矩阵存储结构最大的优点就是简单直观,易于理解和实现。其适用范围广泛,有向图、无向图、混合图、带权图等都可以直接用邻接矩阵表示。另外,对于很多操作,比如获取顶点度数,判断某两点之间是否有连边等,都可以在常数时间内完成。然而,它的缺点也是显而易见的:从以上的例子我们可以看出,对于一个有 n 个顶点的图,邻接矩阵总是需要 n^2的存储空间。当边数很少的时候,就会造成空间的浪费。因此,具体使用哪一种存储方式,要根据图的特点来决定:如果是稀疏图,我们一般用邻接表来存储,这样可以节省空间;如果是稠密图,考虑到邻接表中要附加链域,我们一般用邻接矩阵来存储。

你可能感兴趣的:(数据结构)