图的邻接矩阵存储方式是两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组(即为邻接矩阵)存储图中的边或弧的信息
设图G有n个顶点,则邻接矩阵为一个n×n的方阵,定义为:
抽象数据类型如下
typedef struct Graph
{
char vexs[MAXSIZE];
int arc[MAXSIZE][MAXSIZE];
int numVertexes, numEdges;
}MGraph;
我们设置一个顶点数组为vertex[]={v0,v1,v2,v3…} 边数组为一个对称矩阵,该矩阵关于对角线对称,对角线的元素均为0,因为对角线的元素如 **arc[0][0],arc[1][1]**都是顶点到自身的边,而因为是无向图,所以关于对角线对称。
对于有向图,主对角线的元素依旧为零,但是因为为有向图,所以不一定对称。而有向图的入度和出度入度为v1列各数之和,出度为v1列各数之和。
如果对于带有权值的有向图,设图G是网图,有n个顶点,则邻接矩阵是一个n×n的方阵,定义为
邻接矩阵代码如下
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
#define INFINITY 65535
typedef struct Graph
{
char vexs[MAXSIZE];
int arc[MAXSIZE][MAXSIZE];
int numVertexes, numEdges;
}MGraph;
//建立无向网图的邻接矩阵
void CreatMGraph(MGraph* G)
{
int m, n, w;
printf("请输入你的顶点数和边数\n");
scanf("%d %d", &G->numVertexes, &G->numEdges);
for (int i = 0; i < G->numVertexes; i++)
scanf(&G->vexs[i]);
for (int i = 0; i < G->numVertexes; i++)
for (int j = 0; j < G->numVertexes; j++)
G->arc[i][j] = INFINITY;
for (int i = 0; i < G->numEdges; i++)
{
printf("请输入边(vi,vj)上的下标,下标和权\n");
scanf("%d %d %d", &n, &m, &w);
G->arc[n][m] = w;
G->arc[m][n] = w;
}
}
void printMGraph(MGraph* G)
{
for (int i = 0; i < G->numVertexes; i++)
{
for (int j = 0; j < G->numVertexes; j++)
printf("%10d", G->arc[i][j]);
putchar('\n');
}
}
int main()
{
MGraph* G = (MGraph*)malloc(sizeof(MGraph));
CreatMGraph(G);
printMGraph(G);
return 0;
}
而对于邻接矩阵来说,如果存在定点较多,边数较少的稀疏图,我们发现,对于存储空间的浪费很大,所以我们依旧用一个数组存储顶点信息,但是每个顶点的边关系我们用单链表来存储。
所以抽象数据类型为
在这里插入代码片