图的邻接矩阵与邻接表的建立,c/c++描述

2023-11-10

  图里数据节点是多对多的关系。一个节点有多个前驱,也有多个后继。甚至还有无向图,不区分前驱和后继,只需要节点之间有邻接关系即可。因此,描述这种数据关系,需要新的数据结构。
  图有顶点集和边集组成。顶点代表一个数据节点,边代表数据顶点间的邻接关系。
  描述图的数据结构是多种多样的,bilibili里小甲鱼老师也说了,程序编程是没有唯一答案的。能解决问题即可。因为编程的自由度,比数学领域大,不像数学题那样只有唯一一个正确答案。和为数不多的几种解法。程序能解决问题,清晰易懂就是好程序。在前人的基础上改动一些,改进一些,也算是更好的程序。
  图可以用邻接矩阵来描述,包含一个存储所有顶点的数组成员,一个存储顶点间邻接关系的二维矩阵,矩阵元素值表示两个下标对应的两个顶点是否有邻接关系,对于带权边,则矩阵元素值表示对应边的权,还有一个表示顶点数的成员,一个表示边数的成员。如此的一个结构体变量就可以表示图的所有数据信息。
  图也可以用邻接表来表示。因为对于稀疏图来说,用邻接矩阵存储边,太浪费内存。邻接表的结构体成员包括,由单链表表头组成的一维数组和总顶点数成员和总边数成员。每一个表头也是结构体变量:一个成员存储顶点,另一个成员存储指向邻接表节点的指针。邻接表节点也是结构体变量,其一个成员存储与表头顶点邻接的另一个顶点在表头数组里的下标,一个成员存储对应边的权值,最后一个成员是指向下一个表节点的指针。如此,这样的一个邻接表结构体变量也存储了图的所有信息。
  本例题是个练习,包含的函数功能如下:
  函数createGraphAdjMatrix,由图的所有零碎已知信息建立邻接矩阵。
  函数createGraphAdjList,由图的所有零碎已知信息建立邻接表。
  函数matrixToList,由邻接矩阵建立邻接表。
  函数listToMatrix,由邻接表建立邻接矩阵;其实就是对结构体的各成员赋值。
  函数dispalyGraphAdjMatrix,由邻接矩阵输出图的所有信息,以矩阵表示。
  函数displayGrapgAdjList,由邻接表输出图的所有信息,以线性表表示。这两个输出的目的也是为了检测图的结构体变量建立是否准确。
  完整代码如下,先是main函数所在文件代码:

#include<iostream>
#include<stdio.h>
using namespace std;
#define MAXVERTEX 15
#define INFINI 65555

struct GraphAdjaMatrix {
	char vertexes[MAXVERTEX];
	int edges[MAXVERTEX][MAXVERTEX];
	int numVertexes;
	int numEdges;
};

struct AdjaListNode {
	int indexOfVertex;
	int weightOfEdge;
	AdjaListNode* pt;
};

struct AdjListHead {
	char vertex;
	AdjaListNode* pt;
};

struct GraphAdjaList {
	AdjListHead vertexes[MAXVERTEX];
	int numVertexes;
	int numEdges;
};

extern void createGraphAdjMatrix(GraphAdjaMatrix &graphAdjMatrix,
			int numVertexes,int numEdges,int edges[][6],char vertexes[]);
extern void createGraphAdjList(GraphAdjaList &graphAdjList,
			int numVertexes, int numEdges, int edges[][6], char vertexes[]);
extern void matrixToList(GraphAdjaMatrix &graphAdjMatrix, 
			GraphAdjaList &graphAdjList);
extern void listToMatrix(GraphAdjaList &graphAdjList,
	GraphAdjaMatrix &graphAdjMatrix);
extern void dispalyGraphAdjMatrix(GraphAdjaMatrix &graphAdjMatrix);
extern void displayGrapgAdjList(GraphAdjaList &graphAdjList);


int main() {
	GraphAdjaMatrix graphAdjMatrix ;
	GraphAdjaList graphAdjList;
	int numVertexes = 6, numEdges = 10;
	int edges[][6] = {	{0,5,INFINI,7,INFINI,INFINI},
						{INFINI,0,4,INFINI,INFINI,INFINI},
						{8,INFINI,0,INFINI,INFINI,9},
						{INFINI,INFINI,5,0,INFINI,6},
						{INFINI,INFINI,INFINI,5,0,INFINI},
						{3,INFINI,INFINI,INFINI,1,0} };
	char vertexes[] = {'a','b','c','d','e','f'};

	createGraphAdjMatrix(graphAdjMatrix,numVertexes,numEdges,edges,vertexes);
	createGraphAdjList(graphAdjList,numVertexes,numEdges,edges,vertexes);

	GraphAdjaMatrix graphAdjMatrixNew;
	GraphAdjaList graphAdjListNew;

	matrixToList(graphAdjMatrix,graphAdjListNew);
	listToMatrix(graphAdjList,graphAdjMatrixNew);

	dispalyGraphAdjMatrix(graphAdjMatrixNew);
	cout << endl;
	displayGrapgAdjList(graphAdjListNew);

	return 0;
}

  接着是各函数所在源文件代码:

#include<iostream>
#include<stdio.h>
using namespace std;
#define MAXVERTEX 15
#define INFINI 65555

struct GraphAdjaMatrix {
	char vertexes[MAXVERTEX];
	int edges[MAXVERTEX][MAXVERTEX];
	int numVertexes;
	int numEdges;
};

struct AdjaListNode {
	int indexOfVertex;
	int weightOfEdge;
	AdjaListNode* pt;
};

struct AdjListHead {
	char vertex;
	AdjaListNode* pt;
};

struct GraphAdjaList {
	AdjListHead vertexes[MAXVERTEX];
	int numVertexes;
	int numEdges;
};

void createGraphAdjMatrix(GraphAdjaMatrix &graphAdjMatrix,
	int numVertexes, int numEdges, int edges[][6], char vertexes[]) {
	graphAdjMatrix.numVertexes = numVertexes;
	graphAdjMatrix.numEdges = numEdges;
	
	for (int i = 0; i < numVertexes; i++)
		graphAdjMatrix.vertexes[i] = vertexes[i];

	for (int row = 0; row < numVertexes; row++)
		for (int column = 0; column < numVertexes; column++)
			graphAdjMatrix.edges[row][column] = edges[row][column];
}

void createGraphAdjList(GraphAdjaList &graphAdjList,
	int numVertexes, int numEdges, int edges[][6], char vertexes[]){
	graphAdjList.numEdges = numEdges;
	graphAdjList.numVertexes = numVertexes;

	for (int i = 0; i < MAXVERTEX; i++)
		graphAdjList.vertexes[i].pt = NULL;

	for (int i = 0; i < numVertexes; i++)
		graphAdjList.vertexes[i].vertex = vertexes[i];

	AdjaListNode* ptTail = NULL,*ptNew;
	int i, j;
	for ( i = 0; i < numVertexes; i++) 
		for (j = 0; j < numVertexes; j++) 
			if (edges[i][j] != 0 && edges[i][j] != INFINI) {
				ptNew = new AdjaListNode;

				ptNew->indexOfVertex = j;
				ptNew->weightOfEdge = edges[i][j];
			
				if (graphAdjList.vertexes[i].pt == NULL) {
					ptNew->pt = NULL;
					graphAdjList.vertexes[i].pt = ptNew;
					ptTail = ptNew;
				}
				else {
					ptNew->pt = ptTail->pt;
					ptTail->pt = ptNew;
					ptTail = ptNew;
				}
			}
}

void matrixToList(GraphAdjaMatrix &graphAdjMatrix,
		GraphAdjaList &graphAdjList) {
	graphAdjList.numEdges = graphAdjMatrix.numEdges;
	graphAdjList.numVertexes = graphAdjMatrix.numVertexes;

	for (int i = 0; i < MAXVERTEX; i++)
		graphAdjList.vertexes[i].pt = NULL;

	for (int i = 0; i < graphAdjList.numVertexes; i++)
		graphAdjList.vertexes[i].vertex = graphAdjMatrix.vertexes[i];

	AdjaListNode* ptTail = NULL, * ptNew;
	int i, j;
	for (i = 0; i < graphAdjList.numVertexes; i++)
		for (j = 0; j < graphAdjList.numVertexes; j++)
			if (graphAdjMatrix.edges[i][j] != 0 && 
				graphAdjMatrix.edges[i][j] != INFINI) {
				ptNew = new AdjaListNode;

				ptNew->indexOfVertex = j;
				ptNew->weightOfEdge = graphAdjMatrix.edges[i][j];

				if (graphAdjList.vertexes[i].pt == NULL) {
					ptNew->pt = NULL;
					graphAdjList.vertexes[i].pt = ptNew;
					ptTail = ptNew;
				}
				else {
					ptNew->pt = ptTail->pt;
					ptTail->pt = ptNew;
					ptTail = ptNew;
				}
			}
}

void listToMatrix(GraphAdjaList &graphAdjList,
	GraphAdjaMatrix &graphAdjMatrix) {
	graphAdjMatrix.numEdges = graphAdjList.numEdges;
	graphAdjMatrix.numVertexes = graphAdjList.numVertexes;

	for (int i = 0; i < graphAdjMatrix.numVertexes; i++)
		graphAdjMatrix.vertexes[i] = graphAdjList.vertexes[i].vertex;

	int row, column;
	//对邻接矩阵的初始化,主对角线为0,其余统统为无穷大
	for(row = 0 ; row < graphAdjMatrix.numVertexes ; row++)
		for(column = 0 ; column < graphAdjMatrix.numVertexes ; column++)
			if (row == column) 
				graphAdjMatrix.edges[row][column] = 0 ;
			else
				graphAdjMatrix.edges[row][column] = INFINI;
	
	AdjaListNode* pt;
	for (row = 0; row < graphAdjMatrix.numVertexes; row++) {
		pt = graphAdjList.vertexes[row].pt;
		while (pt != NULL) {
			column = pt->indexOfVertex;
			graphAdjMatrix.edges[row][column] = pt->weightOfEdge;
			pt = pt->pt;
		}
	}
}

void dispalyGraphAdjMatrix(GraphAdjaMatrix &graphAdjMatrix) {
	cout << "adjacensy matrix :" << endl;
	int row,column;
	printf("%3c",' ');
	for (row = 0; row < graphAdjMatrix.numVertexes; row++)
		printf("%3c",graphAdjMatrix.vertexes[row]);
	printf("\n");
	for (row = 0; row < graphAdjMatrix.numVertexes; row++) {
		printf("%-3c", graphAdjMatrix.vertexes[row]);
		for (column = 0; column < graphAdjMatrix.numVertexes; column++)
			if (graphAdjMatrix.edges[row][column] == INFINI)
				printf("%3s", "∞");
			else
				printf("%3d",graphAdjMatrix.edges[row][column]);
		cout << endl;
	}
}

void displayGrapgAdjList(GraphAdjaList &graphAdjList) {
	cout << "graph adjacency list :" << endl;
	AdjaListNode* pt;
	for (int i = 0; i < graphAdjList.numVertexes; i++) {
		printf("%2c:",graphAdjList.vertexes[i].vertex);
		pt = graphAdjList.vertexes[i].pt;
		while (pt != NULL) {
			printf("%5d(%d)",pt->indexOfVertex,pt->weightOfEdge);
			pt = pt->pt;
		}
		cout << endl;
	}
}

测试结果如下:
在这里插入图片描述
谢谢阅读

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

图的邻接矩阵与邻接表的建立,c/c++描述 的相关文章

随机推荐

  • Windows10下VTR.7中VPR项目的运行

    下载VTR7和Visual Studio2022 点击sln文件 打开vpr工程 项目升级 vpr为VS2010的项目 需要先对工程文件升级后再编译 取消较小类型检查 上方菜单 项目 VPR属性 C C 代码生成 编译链接 运行 命令行运行
  • Elasticsearch Java 操作之后查询数据未及时更新

    在请求里加这个参数 request setRefreshPolicy WriteRequest RefreshPolicy IMMEDIATE 例如 public boolean saveOrUpdate String indexName
  • ListView具有多种item布局——实现微信对话列 .

    这篇文章的效果也是大家常见的 各种通讯应用的对话列表都是这种方式 像微信 whatsapp 易信 米聊等 我们这篇文章也权当为回忆 形成简单的笔记 这篇文章参考了2009年Google IO中的 TurboChargeYourUI How
  • linux启动,挂栽,共享,忘记密码的解决方法

    Linux修改linux的启动方式 修改linux启动方式 文本方式或xwindow方式 vi etc inittab 找到id x initdefault 一行 x 3为文本方式 x 5为xwindow方式 重启机器即可生效 mount用
  • Leetcode5438. 制作 m 束花所需的最少天数——另类的二分法

    文章目录 引入 二分法题解 制作 m 束花所需的最少天数 二分法题解 分割数组的最大值 二分法题解 两球之间的磁力 引入 之前在周赛遇到5438 制作 m 束花所需的最少天数 给你一个整数数组 bloomDay 以及两个整数 m 和 k 现
  • YOLOV5改进-添加EIoU,SIoU,AlphaIoU,FocalEIoU,Wise-IoU

    在YoloV5中添加EIoU SIoU AlphaIoU FocalEIoU Wise IoU 2023 2 7 更新 yolov5添加Wise IoUB站链接 重磅 YOLO模型改进集合指南 CSDN yolov5中box iou其默认用
  • java 16进制与图片互转

    十六进制转成图片 十六进制转成图片 author Administrator public static void saveToImgFile String src String output if src null src length
  • 使用JMS进行消息传递

    你需要什么 大约 15 分钟 IntelliJ IDEA或其他编辑器 JDK 1 8或更高版本 Maven 3 2 你会建立什么 本指南将指导您完成使用 JMS 代理发布和订阅消息的过程 您将构建一个应用程序 该应用程序使用Spring的
  • 关于项目属性书写应该严重注意的问题

    这样马马虎虎不注意属性的书写细节 会导致属性查询或者注入失败 public class Goods private Integer goodsId private String goodsName private String goodsT
  • C#学习笔记 常用的集合

    列表List lt T gt 列表List lt T gt 实现了IList ICollection IEnumberable IList接口 可以向该列表中动态的添加 删除 查找元素 如果列表中的元素满了 会动态分配一个容量是原来两倍的列
  • Docker 的基本概念和优势

    Docker是一个开源的容器化平台 可以将应用程序和所有依赖项打包在一起 形成一个独立的 可移植的容器 以下是Docker的基本概念和优势 基本概念 Docker镜像 Docker镜像是一个包含应用程序和所有依赖项的文件系统 它可以用来创建
  • 服务器系统如何账务处理,云服务器费用账务处理

    云服务器费用账务处理 内容精选 换一换 用户支付订单后 如果收到云服务器开通失败的短信 请致电华为云客服中心电话4000 955 988 客服会协助用户排除故障 开通云服务器 如果故障无法及时排除 用户可以选择取消订单 客服会做退费处理 将
  • Maven项目,本地jar包导入手动导入到Maven库中

    当你的项目 由于网络或者环境这些问题 无法从maven中央仓库更新jar包到本地的时候 可以尝试下面方法 手动添加jar包到Maven仓库 方法一 推荐 1 需要先拿到你的jar包 copy到本地 例如我的就是hutool all 5 8
  • sql注入详细过程

    前提 mysql5 0以上版本包含内置的information schema数据库 它储存着mysql所有的数据库和表结构信息 利用该数据库可以查询到所有的数据库和表的内容 一 5 0 暴力破解的方式获取数据 1 原理 当我们的Web ap
  • 运维工程师绩效考核表_运维人员初步 度绩效考核表

    姓 名 部 门 岗 位 上级领导 时 间 考核分类 考核维 度 权重 指标 数据来源 考核评分 复核 10 计划合理 偏差范围可控 10 分 考评 30 按计划完成的时间 30分 考评 10 机房设备的是否正常运行 10 考评 10 网站的
  • 最大流算法 - 标号法

    标号法求最大流 图论中网络的相关概念见上篇博客 算法基本思想 从某个初始流开始 重复地增加流的值到不能再改进为止 则最后所得的流将是一个最大流 为此 不妨将每条边上的流量设置为0作为初始流量 为了增加给定流量的值 我们必须找出从发点到收点的
  • python3.11安装, 解决pip is configured with locations that require TLS/SSL问题

    系统 centos7 4 虚拟机 python版本 本机自带的2 7 5 以及参考python安装的python3 11 pip版本 本机自带的8 1 2 参考pip安装 升级升级到了20 3 4 pip3版本为22 3 1 openssl
  • FPGA实战小项目2

    基于FPGA的贪吃蛇游戏 基于FPGA的贪吃蛇游戏 基于fpga的数字密码锁ego1 基于fpga的数字密码锁ego1 基于fpga的数字时钟 basys3 基于fpga的数字时钟 basys3
  • 正点原子STM32(基于HAL库)4

    目录 ADC 实验 ADC 简介 单通道ADC 采集实验 ADC 寄存器 硬件设计 程序设计 下载验证 单通道ADC 采集 DMA 读取 实验 ADC DMA 寄存器 硬件设计 程序设计 下载验证 多通道ADC 采集 DMA 读取 实验 A
  • 图的邻接矩阵与邻接表的建立,c/c++描述

    图里数据节点是多对多的关系 一个节点有多个前驱 也有多个后继 甚至还有无向图 不区分前驱和后继 只需要节点之间有邻接关系即可 因此 描述这种数据关系 需要新的数据结构 图有顶点集和边集组成 顶点代表一个数据节点 边代表数据顶点间的邻接关系