前言
今天一起学习一下图的存储方法之一的邻接矩阵,这是一种直观的存储图的方法,具体实现代码下一篇文章给出。
一、存储无权图
结构体定义
#define MaxVertexNum 100 //最大顶点数
typedef struct
{
char Vex[MaxVertexNum]; //顶点表
int Edge[MaxVertexNum][MaxVertexNum]; //边表,邻接矩阵
int vexnum, arcnum; //当前顶点数,弧数
}MGrapf;
1.无向图
若两个顶点之间有边,则在邻接矩阵中对应位置做出标记。
如:A、B两个顶点之间边,则将对应位置标记为1。同时由于无向图没有方向,则两个顶点都有到对方的边。可以得出这是一个对称矩阵。可以采用压缩矩阵存储
此时顶点的度就是对应行(或列)中标记数的和。如点A的度为3。
2.有向图
两个顶点之间有弧,在弧头所在行的对应弧尾位置做出标记。如<A,B>则在(0,1)处标记为1。而不存在<B,A>弧,则标记为0.
二、存储带权图/网
#define MAX_INTEGER (~(1<<(sizeof(int)*8-1)))
#define MaxVertexNum 100
/*
表示1左移4*8-1位 然后取反,
int(int为四字节时,int在有的电脑上不是四字节)的最大值,
当两点之间不邻接时,将两点之间的权值设为int的最大值,
在输出时,用“∞”表示。
*/
typedef struct
{
char Vex[MaxVertexNum]; //顶点表
int Edge[MaxVertexNum][MaxVertexNum]; //边的权值
int vexnum, arcnum; //顶点数,弧数
}MGrapf;
存储和无权图类似,但是将标记改变为权值,当两个顶点之间没有边的时候,将权值设置为MAX_INTEGER (最大整数)。
三、性能分析
可以看出,邻接矩阵法的空间复杂度由两部分构成:
顶点表(O(n)),邻接矩阵(O(N^2))。保留高次方,所以邻接矩阵的空间复杂度为O(n ^2);
实际上在顶点较多边少的时候存储的有效信息不是很多,所以邻接矩阵适合存储稠密图
四、性质
这是一个特别神奇的性质。
An(n个矩阵A相乘)的元素An [i][j]等于顶点i到顶点j的长度为n的路径的数目。
如下图中:A2 [1][4]=a11a14+a12a24+a13a34+a14a44=1;其中a11a14(为0)意思是顶点A经过A到达顶点D的路径不存在。a12a24(1),表示顶点A经过B到D的路径存在。后面也是这个类似的思路,就不再展开。
知识回顾和考点总结
1.计算无向图顶点度的时间复杂的为o(n),有向图为出度和入度各为为o(n)。
2.找和顶点相邻的边(入边,出边)类似找度(入度,出度),都是遍历对应行(列)
3.存储带权图实际就是在不带权矩阵的基础上,将矩阵中对应值改为权值,而不存在路径的地方设置为无穷大。
4.由于邻接矩阵的空间复杂度只和顶点数有关而与实际边数无关,所以在存储稠密图的时候比较合适。
5.对称矩阵的压缩,这里不做解释,大家可以去看看其他详细的参考资料
6.性质