第1关:图的邻接矩阵存储及求邻接点操作

  • 任务要求
  • 参考答案
  • 评论2
  • 任务描述
  • 相关知识
    • 顶点集合
    • 边集合
  • 编程要求
  • 测试说明

任务描述

本关任务:要求从文件输入顶点和边数据,包括顶点信息、边、权值等,编写程序实现以下功能。 1)构造无向网G的邻接矩阵和顶点集,即图的存储结构为邻接矩阵。 2)输出无向网G的各顶点和邻接矩阵。 3)输出无向网G中顶点H的所有邻接顶点。

相关知识

图是表达“多对多”的关系的一种数据结构,由非空的有限顶点集合和有限边集合组成。将图的类型定义为枚举类型,在枚举值表中罗列:

enum GraphKind{DG,DN,UDG,UDN}; // 有向图,有向网,无向图,无向网

顶点集合

每个顶点数据类型为VertexType,一个图的顶点集合用数组表示,数组下标表示顶点位置。数组内容包含顶点的信息,图的顶点集合的数据类型定义如下:

 
  1. #define MAX_VERTEX_NUM 20 // 最大顶点个数
  2. typedef char VertexType[16]; // 顶点类型
  3. VertexType vexs[MAX_VERTEX_NUM]; // 顶点向量

将顶点数据类型定义为长度为16的字符数组类型,可以将表示的城市名称存储在计算机中。

边集合

邻接矩阵是表示顶点之间相邻关系的矩阵。设G=(V,E)是具有n顶点的图,则G的邻接矩阵是具有如下性质的n阶方阵:

图及邻接矩阵

网及邻接矩阵

用邻接矩阵来表示一个具有n个顶点的图时,用邻接矩阵中的n×n个元素存储顶点间相邻关系,对于无权图,当邻接矩阵中的元素仅表示相应的边是否存在时,VRType可定义为值为01的枚举类型,0表示两个顶点之间没有边,即没有关系。对于带权图,则为权值,如果两个顶点之间没有边,则用一个很大很大的数代替。将顶点关系类型VRType定义为整型:

typedef int VRType; // 顶点关系边的数据类型

顶点关系边的数据类型类型,对于无权图,用1或0表示相邻否;对于带权图,则为权值。

图的边集合的数据类型定义如下:

 
  1. #define INFINITY INT_MAX // 用整型最大值代替∞
  2. typedef struct
  3. {
  4. VRType adj;
  5. } ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

说明: AcrCellAdjMatrix都是类型的名称,若有定义: AdjMatrix arcs;arcs是一个以元素类型为AcrCell20*20二维数组。上述声明与下面等同: ArcCell arcs [MAX_VERTEX_NUM][MAX_VERTEX_NUM];

图的邻接矩阵存储表示,类型定义如下:

 
  1. struct MGraph
  2. {
  3. VertexType vexs[MAX_VERTEX_NUM]; // 顶点向量
  4. AdjMatrix arcs; // 邻接矩阵
  5. int vexnum, arcnum; // 图的当前顶点数和弧数
  6. GraphKind kind; // 图的种类标志
  7. };

图的邻接矩阵表示法是图的一种顺序存储结构,优点是可以快速判断两个顶点之间是否存在边,可以快速添加边或者删除边,可以快速计算顶点度数、求邻接点的操作等;而其缺点是如果顶点之间的边比较少,会比较浪费空间。

邻接矩阵具有如下性质: (1)图中各项点的序号确定后,图的邻接矩阵是唯一确定的; (2)无向图和无向网的邻接矩阵是一个对称矩阵; (3)无向图邻接矩阵中第i行(或第i列)的非0元素的个数即为第i个顶点的度; (4)有向图邻接矩阵中第i行非0元素的个数为第i个顶点的出度,第i列非0元素的个数为第i个顶点的入度,第i个顶点的度为第i行与第j非0元素个数之和; (5)无向图的边数等于邻接矩阵中非0元素个数之和的一半,有向图的弧数等于邻接矩阵中非0元素个数之和。

编程要求

根据提示,在右侧编辑器补充代码,要求从文件中输入顶点和边数据,包括顶点信息、边、权值等,编写函数实现图的基本运算:

 
  1. void CreateGraphF(MGraph &G);// 采用数组(邻接矩阵)表示法,由文件构造无向网G
  2. void Display(MGraph G); // 输出邻接矩阵存储表示的图G
  3. int LocateVex(MGraph G,VertexType u);//若G中存在顶点u,则返回该顶点在图中位置;否则返回-1
  4. VertexType& GetVex(MGraph G,int v); // v是G中某个顶点的序号,返回v的值
  5. int FirstAdjVex(MGraph G,VertexType v);//v是图G中某个顶点,返回v的第一个邻接顶点的序号。若顶点在G中没有邻接顶点,则返回-1
  6. int NextAdjVex(MGraph G,VertexType v,VertexType w);//v是G中某个顶点,w是v的邻接顶点,返回v的(相对于w的)下一个邻接顶点的序号,若w是v的最后一个邻接顶点,则返回-1
  7. void DestroyGraph(MGraph &G); // 销毁图G

测试说明

平台会对你编写的代码进行测试:

测试输入: 3 lt.txt 武汉

输入说明: 第一行输入3,表示输入图的类型为无向网。 第二行输入文件名,该文件里保存了图的数据信息,内容如下: 6 9 武汉 上海 长沙 南京 成都 广州 武汉 长沙 9 武汉 成都 2 长沙 上海 2 长沙 南京 2 上海 南京 5 上海 广州 4 上海 成都 3 南京 广州 8 成都 广州 6

第1行为图的顶点的个数n; 第2行为图的边的条数m; 第3行至第n+2行是n个顶点的数据; 第n+3行至第n+m+2行是m条边的数据; 最后输入一个顶点的数据

预期输出: 无向网 6个顶点9条边。顶点依次是: 武汉 上海 长沙 南京 成都 广州 图的邻接矩阵: ∞ ∞ 9 ∞ 2 ∞ ∞ ∞ 2 5 ∞ ∞ 9 2 ∞ 2 ∞ ∞ ∞ 5 2 ∞ ∞ ∞ 2 ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ 长沙 成都

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h>
#include<limits.h> 

typedef int VRType;    // 顶点关系类型 
typedef char VertexType[20]; // 顶点类型 
// 图的数组(邻接矩阵)存储表示 
#define INFINITY INT_MAX // 用整型最大值代替∞ 
#define MAX_VERTEX_NUM 20 // 最大顶点个数 
typedef enum{DG,DN,UDG,UDN}GraphKind; // {有向图,有向网,无向图,无向网} 

typedef struct
{
	VRType adj; // 顶点关系类型。对无权图,用1(是)或0(否)表示相邻否;对带权图,则为权值 
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 二维数组 

typedef struct      // 图的数组(邻接矩阵)存储 
{
	VertexType vexs[MAX_VERTEX_NUM]; // 顶点向量 
	AdjMatrix arcs; // 邻接矩阵 
	int vexnum,arcnum; // 图的当前顶点数和弧数 
	GraphKind kind; // 图的种类标志 
}MGraph;  

void visit(VertexType i);

void CreateGraphF(MGraph &G);// 采用数组(邻接矩阵)表示法,由文件构造无向网G
void Display(MGraph G);    // 输出邻接矩阵存储表示的图G
int LocateVex(MGraph G,VertexType u);//若G中存在顶点u,则返回该顶点在图中位置;否则返回-1 
VertexType* GetVex(MGraph G,int v);    // v是G中某个顶点的序号,返回v的值
int FirstAdjVex(MGraph G,VertexType v);//v是图G中某个顶点,返回v的第一个邻接顶点的序号。若顶点在G中没有邻接顶点,则返回-1 
int NextAdjVex(MGraph G,VertexType v,VertexType w);//v是G中某个顶点,w是v的邻接顶点,返回v的(相对于w的)下一个邻接顶点的序号,若w是v的最后一个邻接顶点,则返回-1 
void DestroyGraph(MGraph &G); // 销毁图G 




int main()
{
	MGraph g;
	VertexType v1,v2;
	CreateGraphF(g);      // 利用数据文件创建邻接矩阵表示的图	
	Display(g);           // 输出图  
	int i,j,k,n;
	//printf("请输入顶点的值: ");
	scanf("%s",v1);
	//printf("输出图G中顶点%s的所有邻接顶点: ",v1);
	k=FirstAdjVex(g,v1);
	while(k!=-1)
	{ 
		strcpy(v2, g.vexs[k] );
		visit(v2);
		k=NextAdjVex(g,v1,v2);
	}
	printf("\n");    
	return 0;
}

void visit(VertexType i)
{
	printf("%s ",i);
}


void CreateGraphF(MGraph &G)
{
	// 采用数组(邻接矩阵)表示法,由文件构造无向网G
	/********** Begin **********/
	int i,j,k,w;
	char filename[13];
	VertexType va,vb;
	FILE * graphlist;
	scanf("%d",&G.kind);
	scanf("%s",filename);
	graphlist=fopen(filename,"r");

	fscanf(graphlist,"%d",&G.vexnum);
	fscanf(graphlist,"%d",&G.arcnum);
	for(i=0;i<G.vexnum;i++)
		fscanf(graphlist,"%s",G.vexs[i]);
	for(i=0;i<G.vexnum;++i)
		for(j=0;j<G.vexnum;++j){
			if(G.kind%2)
				G.arcs[i][j].adj=INFINITY;
			else
				G.arcs[i][j].adj=0;
		}
	for(k=0;k<G.arcnum;++k){
		if(G.kind%2)
			fscanf(graphlist,"%s%s%d",va,vb,&w);
		else
			fscanf(graphlist,"%s%s",va,vb);
		i=LocateVex(G,va);
		j=LocateVex(G,vb);
		if(G.kind==0)
			G.arcs[i][j].adj=1;
		else if(G.kind==1)
			G.arcs[i][j].adj=w;
		else if(G.kind==2)
			G.arcs[i][j].adj=G.arcs[j][i].adj=1;
		else
			G.arcs[i][j].adj=G.arcs[j][i].adj=w;
	}
	fclose(graphlist);
	/********** End **********/
}


void Display(MGraph G)
{
	// 输出邻接矩阵存储表示的图G
	/********** Begin **********/
	int i,j;
	switch(G.kind){
		case DG:printf("有向图\n");break;
		case DN:printf("有向网\n");break;
		case UDG:printf("无向图\n");break;
		case UDN:printf("无向网\n");
	}
    printf("%d个顶点%d条边。顶点依次是: ",G.vexnum,G.arcnum);
	for(i=0;i<G.vexnum;++i)
		printf("%s ",G.vexs[i]);
	printf("\n图的邻接矩阵:\n");
	for(i=0;i<G.vexnum;i++){
		for(j=0;j<G.vexnum;j++)
			if(G.kind%2){
				if(G.arcs[i][j].adj==INFINITY)
					printf("%s\t","∞");
				else
					printf("%d\t",G.arcs[i][j].adj);
			}else
				printf("%d\t",G.arcs[i][j].adj);
		printf("\n");
	}
	/********** End **********/
}


int LocateVex(MGraph G,VertexType u)
{
	//初始条件:图G存在,u和G中顶点有相同特征
	// 操作结果:若G中存在顶点u,则返回该顶点在图中位置;否则返回-1 
	/********** Begin **********/
    int i;
	for(i=0;i<G.vexnum;++i)
		if(strcmp(u,G.vexs[i])==0) return i;
	return -1;  
	/********** Begin **********/
}

VertexType* GetVex(MGraph G,int v)
{ 
	// 初始条件:图G存在,v是G中某个顶点的序号。操作结果:返回v的值
	/********** Begin **********/
	if(v>=G.vexnum || v<0)
		exit(0);
	return &(G.vexs[v]); 
	/********** End **********/
}



int FirstAdjVex(MGraph G,VertexType v)
{
 	// 初始条件:图G存在,v是G中某个顶点 
	// 操作结果:返回v的第一个邻接顶点的序号。若顶点在G中没有邻接顶点,则返回-1 
	/********** Begin **********/
	int i,j,k;
	if(G.kind%2)
		j=INFINITY;
	else
		j=0;
	k=LocateVex(G,v);
	for(i=0;i<G.vexnum;i++)
		if(G.arcs[k][i].adj!=j)
			return i;
	return -1;
	/********** End **********/
}

int NextAdjVex(MGraph G,VertexType v,VertexType w)
{
	// 初始条件:图G存在,v是G中某个顶点,w是v的邻接顶点 
	// 操作结果:返回v的(相对于w的)下一个邻接顶点的序号,若w是v的最后一个邻接顶点,则返回-1 
	/********** Begin **********/
	int i,j,k1,k2;
	if(G.kind%2)
		j=INFINITY;
	else
		j=0;
	k1=LocateVex(G,v);

	k2=LocateVex(G,w);

	for(i=k2+1;i<G.vexnum;i++)
		if(G.arcs[k1][i].adj!=j)
			return i;
	return -1;
	/********** End **********/
}


void DestroyGraph(MGraph &G)
{ // 初始条件:图G存在。操作结果:销毁图G 
	/********** Begin **********/
	int i,j,k=0;
	if(G.kind%2) 
		k=INFINITY; 
	G.vexnum=0; 
	G.arcnum=0; 
	/********** End **********/
}

输出说明: 第一行输出图的类型。 第二行起输出图的顶点和边的数据信息。 最后一行输出输入顶点的所有邻接点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/171778.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

配置文件自动提示

1、引入依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId> </dependency> 2、修改IDEA配置

mysql底层是如何存放数据的

总览 首先总的来说&#xff0c;分为四个层级&#xff0c;行页区段。行就是数据库里的一行数据。 但一次从磁盘读进内存的数据量是一页&#xff08;页是读写的单位&#xff0c;默认16KB一页&#xff09;&#xff0c;页分很多种类&#xff0c;例如数据页、溢出页、undo日志页。 …

OpenAI宫斗,尘埃落定,微软成最大赢家

周末被OpenAI董事会闹剧刷屏,ChatGPT之父Sam Altman前一天被踢出董事会,免职CEO,后一天重返OpenAI,目前结局未知。 很多同学想要围观,缺少背景知识,这里老章为大家简单介绍前因后果及涉及的人物,时间线,让大家轻松围观。 备好瓜子,开始。 1、主角 先看一张图,看一…

Java基于B/S架构,包括PC后台管理端、APP移动端、可视化数据大屏的智慧工地源码

智慧工地管理平台充分运用数字化技术&#xff0c;聚焦施工现场岗位一线&#xff0c;依托物联网、互联网、AI等技术&#xff0c;围绕施工现场管理的人、机、料、法、环五大维度&#xff0c;以及施工过程管理的进度、质量、安全三大体系为基础应用&#xff0c;实现全面高效的工程…

无人售货奶柜:颠覆传统零售行业的潜力黑马

无人售货奶柜&#xff1a;颠覆传统零售行业的潜力黑马 无人售货奶柜具备体积小、灵活运用空间、无需人工看守和自动结算等特点。相较于传统建店方式&#xff0c;它的成本大大降低&#xff0c;从而提高了运营效率。此外&#xff0c;无人售货奶柜独特的优势之一就是可以保持24小时…

【GUI】-- 11 贪吃蛇小游戏之绘制静态的小蛇

GUI编程 04 贪吃蛇小游戏 4.2 第二步&#xff1a;绘制静态的小蛇 现在绘制静态的小蛇(即小蛇初始位置)&#xff0c;并且完善游戏默认初始状态。这一步还在GamePanel类中实现。 首先&#xff0c;定义了小蛇的数据结构&#xff0c; //定义蛇的数据结构int length; //小蛇总长…

LeetCode【45】跳跃游戏2

题目&#xff1a; 思路&#xff1a; 注意和跳跃游戏【55】不同的是&#xff0c;题目保证可以跳到nums[n-1];那么每次跳到最大即可 代码&#xff1a; public class LeetCode45 {public static int jump(int[] nums) {int jumps 0;int currentEnd 0;int farthest 0;for(int…

案例研究|北京交通大学基于DataEase开展多场景校园数据分析与展示

北京交通大学是教育部直属&#xff0c;教育部、交通运输部、北京市人民政府和中国国家铁路集团有限公司共建的全国重点大学&#xff0c;是国家“211工程”“985工程优势学科创新平台”“双一流”建设高校。 多年来&#xff0c;北京交通大学积极发挥信息技术赋能学校人才培养、…

STM32 -Bin/Hex文件格式解析

文章目录 1. 概述2. Hex文件2.1 格式解析2.2 数据类型2.3 举例解析2.4 合并两个Hex文件方法 3 总结&#xff08;未完待续&#xff09; 1. 概述 Hex文件&#xff1a;它是单片机和嵌入式工程编译输出的一种常见的目标文件格式&#xff08;比如keil就能编译输出hex文件&#xff0…

Rockchip Clock

一:概述 1、时钟子系统 本章节所指的时钟是给SOC各个组件提供时钟的树状框架,而非内核使用的时钟。和其他模块一样,CLOCK也有框架,用以适配不同的平台。适配层之上是客户代码和接口,也就是各模块(如需要时钟信号的外设)的驱动。适配层之下是具体的SOC的时钟操作细节。…

Rust错误处理机制:优雅地管理错误

大家好&#xff01;我是lincyang。 今天&#xff0c;我们要探讨的是Rust语言中的错误处理机制。 Rust作为一种系统编程语言&#xff0c;对错误处理的重视程度是非常高的。它提供了一套既安全又灵活的机制来处理可能出现的错误。 Rust错误处理的两大类别 在Rust中&#xff0…

Flutter:多线程Isolate的简单使用

在flutter中如果要使用线程&#xff0c;需要借助Isolate来实现。 简介 在Flutter中&#xff0c;Isolate是一种轻量级的线程解决方案&#xff0c;用于在应用程序中执行并发任务。Isolate可以被认为是独立于主线程的工作单元&#xff0c;它们可以在后台执行任务而不会阻塞应用程…

影像仪自行更换RGB光源,“看得清,测得准”!

影像仪作为一种现代化高精度测量设备&#xff0c;在各行各业都有着广泛的应用。而RGB表光作为影像仪中的一个关键技术&#xff0c;也是实现图像真实还原的重要因素之一。 **什么是RGB表光&#xff1f;**RGB是指红&#xff08;Red&#xff09;、绿&#xff08;Green&#xff09;…

vue动态获取目录结构进行配置静态路由

文章目录 前言定义项目页面格式一、vite 配置动态路由新建 /router/utils.ts引入 /router/utils.ts 二、webpack 配置动态路由总结如有启发&#xff0c;可点赞收藏哟~ 前言 项目中动态配置路由可以减少路由配置时间&#xff0c;并可减少配置路由出现的一些奇奇怪怪的问题 路由…

Postman的各种参数你都用对了吗?

大家好&#xff0c;我是G探险者。 Postman我们都不陌生&#xff0c;作为一个广泛使用的 HTTP 客户端&#xff0c;平时我们使用它来测试接口&#xff0c;无非就是把接口的url放进去&#xff0c;然后根据请求类型get或者post,在不同位置传一下参数&#xff0c;除了常见的 Params…

机器学习第11天:降维

文章目录 机器学习专栏 主要思想 主流方法 投影 二维投射到一维 三维投射到二维 流形学习 PCA主成分分析 介绍 代码 内核PCA 具体代码 LLE 结语 机器学习专栏 机器学习_Nowl的博客-CSDN博客 主要思想 介绍&#xff1a;当一个任务有很多特征时&#xff0c;我们…

Foodpanda API连接的艺术:无代码开发如何集成营销系统和广告推广工具

连接Foodpanda和电商平台的无代码开发 Foodpanda不仅是一家提供快速外卖服务的国际品牌&#xff0c;而且其创新的技术解决方案还能帮助电商企业优化系统运营。通过无代码开发的方法&#xff0c;即使没有专业的API开发知识&#xff0c;商家也能实现高效的电商系统和客服系统连接…

第3关:图的广度遍历

500 任务要求参考答案评论2 任务描述相关知识编程要求测试说明 任务描述 本关任务&#xff1a;以邻接表存储图&#xff0c;要求编写程序实现图的广度优先遍历。 相关知识 广度优先遍历类似于树的按层次遍历的过程。 假设从图中某顶点v出发&#xff0c;在访问了v之后依次访…

区块链技术与应用 【全国职业院校技能大赛国赛题目解析】第五套智能合约安全漏洞测试

第五套题的智能合约安全漏洞测试题目 环境 : ubuntu20 Truffle v5.8.3 (core: 5.8.3) Ganache v7.8.0 Solidity v0.8.3 Node v18.16.0 Web3.js v1.8.2 前言 请在测试的时候开启ganache打开,并且在truffle的配置文件配好ganache,之前两个帖子忘说了/(ㄒoㄒ)/~~ truffle-con…