当前位置: 首页 > news >正文

【数据结构】使用C语言建立邻接矩阵表示有向图

有向图的邻接矩阵构建

有向图的定义

先回顾下有向图的定义:

有向图是一副具有方向性的图,是有一组顶点和一组有方向的边组成的,每条方向的边都连接着一对有序的顶点。

有向图的邻接矩阵的特点

有向图邻接矩阵中第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;

该结构体由一个顶点表(存储所有会出现的顶点),一个邻接矩阵(用来表示有向图),vexnumarcnum两个变量用来表示当前图的节点数和边数。

创建空图

现在可以编写一个创建有向图的方法,创建的方法有几个要点:

  • 创建出来的图没有任何顶点和边,所以vexnumarcnum两个变量都为0
  • 有向图的邻接矩阵在初始状态的时候都为0
Graph createMaxtrixGraph()
{Graph graph = malloc(sizeof(struct MaxtrixGraph));graph->vexnum = graph->arcnum = 0;    // 刚创建图的时候没有顶点和边// 由于是定义有向图 所以把矩阵中所有的值初始化为0for (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;    // 将该边在矩阵中的位置赋值为1G->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

可以看到邻接矩阵的信息已经被打印出来了。


http://www.mrgr.cn/news/176.html

相关文章:

  • 【Redis】Redis典型应用-缓存(cache)
  • 超精细CG杰作:8K壁纸级官方艺术插画,展现极致美丽与细节的汉服女孩
  • 打卡学习Python爬虫第三天|电影天堂案例
  • 美团笔试-测试方向
  • html+css网页设计 淘宝登录页面
  • Docker 日志管理
  • Go Channel 详解
  • docker 部署 遇到的一些问题
  • Redis 哈希(Hash)
  • leetcode108.把升序数组转换成二叉搜索树
  • 【速览】数据库-MySQL(更新中)
  • 百度AI智能云依赖库OpenSSL库和Curl库及jsoncpp库安装
  • ArcGIS Pro 实现人口分布栅格TIFF数据的网格提取与可视化
  • [C/C++] 基本数据类型
  • HTML常用标签和CSS的运用,以及使用HTML做一个简历
  • ASPICE标准与汽车网络安全:协同确保软件质量与系统安全
  • [数据集][目标检测]电力场景轭式悬架锈蚀分类数据集6351张2类别
  • http和https的区别
  • 软件测试---接口测试
  • arcgis打开不同tif格式编码的栅格数据