上个博客讲过了图的基本概念后,我们来实现图的存储之一————有向图的矩阵法存储。
首先我们来看以下有向带权图:
这样的图适合用矩阵法来存储。
分析一下我们需要的结构:二维数组,表示顶点的字符串,存储顶点的容器,表示定点数量,表述边的数量,
边的指向向用向量坐标的形式,也就是坐标法表示(A,B)和(B,A)在二维数组中表示的概念是不一样的是一个道理。
所以我们来动手操作一下:
第一步:我先准备表示顶点的字符串和边的类型表示
typedef char VertexType[4];
typedef int VRType;
起别名,更清晰
第二步 将矩阵法表示图封装成结构体:
也就是边的数量,定点数量,存储顶点,存储边向和权值的矩阵;
typedef struct graph {
int arcnum;//边数
int vernum;//顶点数
VertexType vetex[10]; //存储顶点
VRType martrix[10][10];//存储权值
}GRA,*LPGRA;
然后就是表的创建,创建表,我们需要知道有多少个顶点,边,让用户去输入,还有边的信息,这样才能创建并存储。
我们在二维数组里面存储需要知道顶点位置,所以我们要利用一维数组的顶点数组里面找到其对应的位置,所以需要一个函数专门比较并查找。
下面是我实现的代码部分:
int searchpos(LPGRA G,VertexType x) {//查找顶点坐标
for (int i = 0; i < G->vernum; i++) {
if (strcmp(G->vetex[i], x) == 0)
return i;
}
return -1;
}
LPGRA creategra() {
LPGRA G = (LPGRA)malloc(sizeof(GRA));
printf("请输入边数和顶点数:");
scanf("%d%d", &G->arcnum, &G->vernum);
printf("请输入%d 个顶点:", G->vernum);
for (int i = 0; i < G->vernum; i++) {
scanf("%s", G->vetex[i]);
}
memset(G->martrix, 0, sizeof(int) * 100);//附上初值,这里是二维数组,所以是10*10(因为C语言的二维数组其实是多个一维数组连续的拼接而成所以能这样使用)
printf("请输入边的信息(左右端点,权值):");
VertexType v1, v2;//两个顶点
VRType vrt;//权值
for (int i = 0; i < G->arcnum; i++) {
scanf("%s%s%d", v1, v2, &vrt);
int posi = searchpos(G,v1);//查找左端点的坐标
int posj = searchpos(G, v2);//查找右端点的坐标
G->martrix[posi][posj] = vrt;
}
return G;
}
其实这种结构就像我们学过的向量一样,前后点的坐标相组合就是它的向量坐标表示出来相对位置,长度存储在它相应的位置就可以
如下图:
这样是不是很清晰。
下面我们来检验一下,我们的存储法是不是和上面我们自己分析的那样子一样
void print(LPGRA G) {
for (int i = 0; i < G->vernum; i++) {
printf("\t%s ", G->vetex[i]);
}
printf("\n");
for (int i = 0; i < G->vernum; i++) {
printf("%s\t", G->vetex[i]);
for (int j = 0; j < G->vernum; j++) {
printf("%d\t",G->martrix[i][j]);
}
printf("\n");
}
}
int main() {
LPGRA G = creategra();
print(G);
}
我的结果
好了,我们实现了,这种存储,有一定的用处吧。
是不是很简单。