前言
从前两篇文章所学习的概念不难看出,图是一种二维平面式的数据结构。因此借助二维数组,可以很好地在计算机中展现顶点之间边的信息。我们借助一维数组存储顶点集合,借助二维数组存储顶点之间边的联通,这种实现方法叫做图的邻接矩阵实现。
邻接矩阵的定义和实现
邻接矩阵的存储结构主体是分为两个部分,即一个用于存放顶点信息的一维数组和一个存放顶点间边信息的二维数组。
一维数组vex用于存放顶点信息,在图中,每个顶点都有各自独具的名称,而这个一维数组就是将这些名称转换成数组对应的下标。
二维数组edge用于存放顶点间边的信息。如果下标为i处的顶点到下表为j处的顶点有弧,则edge[i]置为1,反之则为0。
在无向图中,由于顶点之间一旦存在边,那么两顶点之间均可以相互连通。所以在用邻接矩阵法实现图时,一旦edge[i][j]为1,那么edge[j][i]也为1;同样的,如果edge[i][j]为0,则edge[j][i]也为0。
而在有向图中,顶点a到顶点b有弧,只能代表顶点a到顶点b连通,并不能代表从b到a也连通。所以在有向图的邻接矩阵中,如果edge[i][j]为1,并不能说明edge[j][i]也为1。
以下是图结构体MGraph在C++中的实现:
#define maxNum 50//代表邻接矩阵顶点的最大数目
struct MGraph {
char vex[maxNum];//这里也可以是其他类型,比如字符串型,代表顶点的类型
int edge[maxNum];//这里只需要存放0和1两个数字,如果使用单子节数据类型能够节省空间,这里定义仍为整型
};
邻接矩阵的性质
使用邻接矩阵法实现图具有几种特点:
-
在无向图中,由于任意
edge[i][j]一定等于edge[j][i],因此邻接矩阵一定是一个对称矩阵(可以利用这一特点将无向图的edge数组进行压缩存储); -
对于无向图,邻接矩阵的第i行(或第i列)所有值为1的数据个数之和正好为下标i对应的顶点的度;
-
对于有向图,邻接矩阵的第i行所有值为1的数据个数之和正好为下标i对应的顶点的出度,而第j列所有值为1的数据个数之和正好为下标j对应的顶点的入度;
-
(拓展)设邻接矩阵为,那么对应的任意元素就是下标为i的顶点到下标为j的顶点长度为的路径的数目。
邻接矩阵的优缺点
优点
- 实现较为容易;
- 易于确定顶点之间是否有边相连。
缺点
- 二维数组的方式进行存储,占用空间太大;
- 顶点的出度和入度必须通过遍历对应行(列)的数据元素才能得到(时间复杂度O(n)),浪费时间。
适用
邻接矩阵法适用于边较为密集的稠密图的存储,边越密集,邻接矩阵法的空间利用率就越高。