一. 图的储存结构
【1.1 邻接矩阵】
图的邻接矩阵存储方式是用两个数组来表示图。
一个一维数组存储顶点信息,一个二维数组(邻接矩阵)存储边的信息。
设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为:
看一个实例,下图左就是一个无向图。
从上面可以看出,无向图的边数组是一个对称矩阵。
所谓对称矩阵就是n阶矩阵的元满足aij = aji。
- 从这个矩阵中,很容易知道图中的信息:
- (1)判断任意两顶点是否有边连接;
- (2)某个顶点的度就是顶点vi在邻接矩阵中第i行或(第i列)的元素之和;
- (3)顶点vi的所有邻接点就是矩阵中第i行元素arc[i][j]为1的点;
而有向图讲究入度和出度,vi入度为1,是第i列各数之和;vi出度为2,是第i行各数之和。
若图G是网图,有n个顶点,则邻接矩阵是一个n*n的方阵,定义为:
其中,w[i][j]表示(vi,vj)边上的权值。
//【图的储存---邻接矩阵】O(n^2)
#define MaxN 20
int G[MaxN][MaxN];
void add_sqr(){
int v1,v2,w,n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++) G[i][j]=0;
for(int i=0;i<m;i++){
scanf("%d%d%d",&u,&v,&w);
G[u][v]=w; G[v][u]=w; //无向图,双向边
}
}
从代码中可以得到,时间复杂度为O(n + n^2 + e),
其中对邻接矩阵Grc的初始化耗费了O(n^2)的时间。(部分引用自 这里)
【1.2 邻接表】
对于边数相对顶点较少的图,邻接矩阵极大浪费了存储空间。
因此,有一种数组与链表相结合的存储方法称为邻接表。
邻接表的处理方法是这样的:
(1)顶点用一维数组或单链表来存储,不过数组更便捷。
(2)图中每个顶点vi的所有邻接点构成一个线性表,由于邻接点个数不定,
所以要用单链表存储,这种链表在无向图称为顶点vi的边表。
在有向图中则被称为顶点vi作为弧尾的出边表。
例如,下图就是一个无向图的邻接表的结构。