有向图的邻接矩阵构建
有向图的定义
先回顾下有向图的定义:
有向图是一副具有方向性的图,是有一组顶点和一组有方向的边组成的,每条方向的边都连接着一对有序的顶点。
有向图的邻接矩阵的特点
有向图邻接矩阵中第i行非零元素的个数为第i个顶点的出度,第i列非零元素的个数为第i个顶点的入度,第i个顶点的度为第i行与第i列非零元素个数之和。
开始构建
本篇博客我们使用邻接矩阵来表示有向图,结构体可以这样定义:
#include <stdio.h>
#include <stdlib.h>
#define MVNum 10 // 图的最大的顶点的数量
/*
* 现在构建一个有向图
*/
typedef char VerTexType; // 图的每个结点的类型
typedef struct MaxtrixGraph{
VerTexType vexs[MVNum]; // 顶点表
int arcs[MVNum][MVNum]; // 邻接矩阵
int vexnum,arcnum; // 定义图当前的节点数和边数
} * Graph;
该结构体由一个顶点表(存储所有会出现的顶点),一个邻接矩阵(用来表示有向图),vexnum
和arcnum
两个变量用来表示当前图的节点数和边数。
创建空图
现在可以编写一个创建有向图的方法,创建的方法有几个要点:
- 创建出来的图没有任何顶点和边,所以
vexnum
和arcnum
两个变量都为0 - 有向图的邻接矩阵在初始状态的时候都为0
Graph createMaxtrixGraph()
{
Graph graph = malloc(sizeof(struct MaxtrixGraph));
graph->vexnum = graph->arcnum = 0; // 刚创建图的时候没有顶点和边
// 由于是定义有向图 所以把矩阵中所有的值初始化为0
for (int i=0; i<MVNum; i++)
{
for (int j=0; j<MVNum; j++)
{
graph->arcs[i][j] = 0;
}
}
return graph;
}
在上述代码中,我们在方法中申请了一段有向图的内存空间,并将这个图进行初始化,最后将图的指针返回出去。
方法定义完之后,就可以使用方法获取图结构了:
int main()
{
Graph g1 = createMaxtrixGraph();
return 0;
}
添加顶点和边
现在的图只是一张没有顶点和边的”空图“,接着我们就可以编写一下添加顶点和添加边的函数了。
在添加顶点的过程中,需要注意的是:
- 添加顶点是作用在结构体中的
顶点表
中` - 如果图所定义的最大节点数已达到,则不能在添加顶点
实现添加顶点:
// 添加顶点elem到图G中
void addVertex(Graph G,VerTexType elem)
{
// 如果顶点表已满,则不能在添加顶点
if (G->vexnum >= MVNum) return;
G->vexs[G->vexnum] = elem;
G->vexnum++;
}
在添加边的过程中,需要注意的是:
- 两点确定一条边,所以添加边的时候需要给定两个顶点
为了确定这个顶点在顶点表中的索引为多少,我们最好再编写一个函数,用于定位某个顶点再顶点表中的位置.
// 定位顶点在顶点表中的位置
int Located_vex(Graph G,VerTexType elem)
{
for (int i=0; i<G->vexnum; i++)
{
if (G->vexs[i] == elem) return i;
}
return -1; // 如果顶点表中没有顶点,则返回-1
}
// 添加边 a-b
void addEdge(Graph G, VerTexType a, VerTexType b)
{
int i = Located_vex(G,a);
int j = Located_vex(G,b);
if (i!=-1 && j!=-1){
G->arcs[i][j] = 1; // 将该边在矩阵中的位置赋值为1
G->arcnum++; // 边的个数+1
}
}
在这段代码中,展示了如何在图的邻接矩阵表示法中定位顶点的位置以及添加边.
打印邻接矩阵
打印邻接矩阵就很简单了,因为邻接矩阵是nxn
的矩阵,而n
就是顶点的个数
,
所以只需要一个双循环遍历就能够打印出来。
// 打印邻接矩阵
void print_MaxtrixGraph(Graph G)
{
for ( int i = 0; i < G->vexnum; i++){
for (int j = 0; j < G->vexnum; j++){
printf("%d ",G->arcs[i][j]);
}
printf("\n");
}
}
举个例子
这里有一个有向图:
让我们用程序来存储这个有向图吧:
int main()
{
Graph g1 = createMaxtrixGraph();
// 添加顶点 'A' - 'F'
for (char i='A'; i <= 'F'; i++)
{
addVertex(g1,i);
}
// 添加边
addEdge(g1,'A','B');
addEdge(g1,'C','A');
addEdge(g1,'D','A');
addEdge(g1,'E','B');
addEdge(g1,'E','C');
addEdge(g1,'F','B');
addEdge(g1,'F','D');
// 打印邻接矩阵
printf("该图的邻接矩阵为:\n");
print_MaxtrixGraph(g1);
return 0;
}
控制台输出信息为:
该图的邻接矩阵为:
0 1 0 0 0 0
0 0 0 0 0 0
1 0 0 0 0 0
1 0 0 0 0 0
0 1 1 0 0 0
0 1 0 1 0 0
可以看到邻接矩阵的信息已经被打印出来了。