数据结构实验8.1:图的基本操作

文章目录

  • 一,实验目的
  • 二,实验内容
  • 三,实验要求
  • 四,算法分析
  • 五,示例代码
    • 8-1.cpp源码
    • graph.h源码
  • 六,操作步骤
  • 七,运行结果


一,实验目的

1.掌握图的邻接矩阵、邻接表的表示方法及建立算法;
2.掌握图的深度优先遍历、广度优先遍历等基本操作的算法;
3.掌握图的最小生成树、关键路径等应用问题的求解算法;
4.进一步加深对图的几种基本应用算法的理解,逐步培养解决实际问题的编程能力。

二,实验内容

已知无向连通图G如下图所示。完成图的下列基本操作:
(1)建立图的邻接矩阵,输出邻接矩阵;
(2)建立图的邻接表,输出邻接表;
(3)求邻接表表示的图的深度优先遍历序列;
(4)求邻接矩阵表示的图的深度优先遍历序列;
(5)求邻接表表示的图的广度优先遍历序列;
(6)求邻接矩阵表示的图的广度优先遍历序列。
在这里插入图片描述

三,实验要求

(1)建立头文件graph.h,其中定义了图的邻接矩阵和邻接表表示的存储结构,本实验的其它实验题目也可共享使用,其代码如下:

#define MAXV 30      			// 最大顶点数
typedef int InfoType;
//以下定义图的邻接矩阵数据结构
typedef struct {					//定义图的顶点结构int no;						//顶点编号InfoType info;					//顶点其它信息,可用于
} VertexType;
typedef struct {					//定义图邻接矩阵VertexType vexs[MAXV];		//顶点向量int arcs[MAXV][MAXV];		//邻接矩阵int vexnum, arcnum;			//图的当前顶点数和边数
} MGraph;
//以下定义图的邻接表数据结构
typedef struct ArcNode {			//定义表结点类型int  adjvex;					//顶点序号int  weight;					//边或弧的权值struct ArcNode *nextarc;		//指向下一个表结点的指针
} ArcNode;
typedef struct VNode {				//定义头结点类型VertexType data;ArcNode *firstarc;
} VNode
//typedef  VNode  AdjList[MAXV];	//定义头结点数组
typedef struct {					//定义图的邻接表类型VNode  vertices[MAXV];int  vexnum, arcnum;
} LGraph;

(2)完善参考程序,在程序中的下划线处填写适当的语句。
(3)设计测试数据,调试、测试完善后的参考程序,保存和打印测试结果,对结果进行分析。

四,算法分析

(1)深度优先搜索遍历算法
从图中某顶点v出发:
① 访问顶点v;
② 依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问;
③ 若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。

(2)广度优先搜索遍历算法
从图中某顶点vi出发:
① 访问顶点vi ;
② 访问vi 的所有未被访问的邻接点w1 ,w2 , …wk ;
③ 依次从这些邻接点(在步骤②中访问的顶点)出发,访问它们的所有未被访问的邻接点; 依此类推,直到图中所有访问过的顶点的邻接点都被访问;
④ 若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行广度优先搜索遍历,直到图中所有顶点均被访问过为止。
为实现③,需要保存在步骤②中访问的顶点,而且访问这些顶点的邻接点的顺序为:先保存的顶点,其邻接点先被访问。

五,示例代码

8-1.cpp源码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include "graph.h"// 访问标志数组
int visited[MAXV];
// 广度优先遍历存储队列
int queue[MAXV];// 建立图的邻接矩阵
void CreatMG(MGraph& mg) {int i, j;int A[7][7];mg.vexnum = 7;mg.arcnum = 9;for (i = 0; i < mg.vexnum; i++) {for (j = 0; j < mg.vexnum; j++) {A[i][j] = 0;}}A[0][1] = A[0][2] = A[0][6] = 1;A[1][3] = 1;A[2][3] = A[2][5] = A[2][6] = 1;A[3][4] = 1;A[5][6] = 1;for (i = 1; i < mg.vexnum; i++) {for (j = 0; j < i; j++) {A[i][j] = A[j][i];}}for (i = 0; i < mg.vexnum; i++) {for (j = 0; j < mg.vexnum; j++) {mg.arcs[i][j] = A[i][j];}}
}// 由图的邻接矩阵创建图的邻接表
void CreatLG(LGraph*& lg, MGraph mg) {int i, j;ArcNode* p;lg = (LGraph*)malloc(sizeof(LGraph));for (i = 0; i < mg.vexnum; i++) {lg->vertices[i].firstarc = NULL;}for (i = 0; i < mg.vexnum; i++) {for (j = mg.vexnum - 1; j >= 0; j--) {if (mg.arcs[i][j] != 0) {p = (ArcNode*)malloc(sizeof(ArcNode));p->adjvex = j;p->weight = mg.arcs[i][j];p->nextarc = lg->vertices[i].firstarc;lg->vertices[i].firstarc = p;}}}lg->vexnum = mg.vexnum;lg->arcnum = mg.arcnum;
}// 输出图的邻接矩阵
void OutputMG(MGraph mg) {int i, j;for (i = 0; i < mg.vexnum; i++) {for (j = 0; j < mg.vexnum; j++) {printf("%3d", mg.arcs[i][j]);}printf("\n");}
}// 输出图的邻接表
void OutputLG(LGraph* lg) {int i;ArcNode* p;for (i = 0; i < lg->vexnum; i++) {p = lg->vertices[i].firstarc;if (p) {printf("%3d:", i);}while (p) {printf("%3d", p->adjvex);p = p->nextarc;}printf("\n");}
}// 邻接表表示的图的递归深度优先遍历
void LDFS(LGraph* lg, int i) {ArcNode* p;printf("%3d", i);visited[i] = 1;p = lg->vertices[i].firstarc;while (p) {if (visited[p->adjvex] == 0) {LDFS(lg, p->adjvex);}p = p->nextarc;}
}// 邻接矩阵表示的图的递归深度优先遍历
void MDFS(MGraph mg, int i) {int j;printf("%3d", i);visited[i] = 1;for (j = 0; j < mg.vexnum; j++) {if (mg.arcs[i][j] != 0 && visited[j] == 0) {MDFS(mg, j);}}
}// 邻接表表示的图的广度优先遍历
void LBFS(LGraph* lg, int s) {int i, v, w, front, rear;ArcNode* p;for (i = 0; i < lg->vexnum; i++) {visited[i] = 0;}front = rear = 0;printf("%3d", s);visited[s] = 1;queue[rear++] = s;while (front < rear) {v = queue[front++];for (p = lg->vertices[v].firstarc; p != NULL; p = p->nextarc) {w = p->adjvex;if (visited[w] == 0) {printf("%3d", w);visited[w] = 1;queue[rear++] = w;}}}
}// 邻接矩阵表示的图的广度优先遍历
void MBFS(MGraph mg, int s) {int i, j, v, front, rear;for (i = 0; i < mg.vexnum; i++) {visited[i] = 0;}front = rear = 0;printf("%3d", s);visited[s] = 1;queue[rear++] = s;while (front < rear) {v = queue[front++];for (i = 0; i < mg.vexnum; i++) {for (j = 0; j < mg.vexnum; j++) {if (mg.arcs[v][j] != 0 && visited[j] == 0) {printf("%3d", j);visited[j] = 1;queue[rear++] = j;}}}}
}int main() {LGraph* lg;MGraph mg;int i;CreatMG(mg);CreatLG(lg, mg);printf("(1)当前图的邻接矩阵是:\n");OutputMG(mg);printf("(2)当前图的邻接表是:\n");OutputLG(lg);for (i = 0; i < mg.vexnum; i++) {visited[i] = 0;}getchar();printf("(3)邻接表表示的图的深度优先遍历序列是:");LDFS(lg, 0);getchar();for (i = 0; i < mg.vexnum; i++) {visited[i] = 0;}printf("(4)邻接矩阵表示的图的深度优先遍历序列是:");MDFS(mg, 0);getchar();printf("(5)邻接表表示的图的广度优先遍历序列是:");LBFS(lg, 0);getchar();printf("(6)邻接矩阵表示的图的广度优先遍历序列是:");MBFS(mg, 0);printf("\n");return 0;
}

graph.h源码

#pragma once
#ifndef GRAPH_H
#define GRAPH_H// 定义图的最大顶点数
const int MAXV = 100;// 定义弧节点结构体
typedef struct ArcNode {int adjvex;int weight;struct ArcNode* nextarc;
} ArcNode;// 定义顶点结构体
typedef struct VNode {ArcNode* firstarc;
} VNode;// 定义邻接表结构体
typedef struct {VNode vertices[MAXV];int vexnum, arcnum;
} LGraph;// 定义邻接矩阵结构体
typedef struct {int arcs[MAXV][MAXV];int vexnum, arcnum;
} MGraph;#endif    

六,操作步骤

1,双击Visual Studio程序快捷图标,启动程序。
在这里插入图片描述

2,之前创建过项目的话,直接打开即可,这里选择【创建新项目】。
在这里插入图片描述

3,单击选择【空项目】——单击【下一步】按钮。
在这里插入图片描述

4,编辑好项目的名称和存放路径,然后单击【创建】按钮。
在这里插入图片描述

5,创建C++程序文件,右击【源文件】——选择【添加】——【新建项】。
在这里插入图片描述
6,输入项目名称8-1.cpp,单击【添加】按钮。
在这里插入图片描述

7,输入项目名称graph.h,单击【添加】按钮,此文件要定义 MGraph、LGraph、ArcNode 等类型,同时定义 MAXV 常量。
在这里插入图片描述

8,编写代码,单击运行按钮,运行程序。
在这里插入图片描述

七,运行结果

1,实验要求的测试结构。
在这里插入图片描述

2,编写代码运行后的结果。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot3 实现定时任务 每10分钟执行一次,同时要解决分布式的问题 区分不同场景

在Spring Boot 3中实现分布式定时任务&#xff0c;确保多实例环境下任务仅执行一次&#xff0c;可以采用以下方案&#xff1a; 方案一&#xff1a;Redis分布式锁&#xff08;推荐&#xff09; import org.springframework.data.redis.core.StringRedisTemplate; import org.sp…

WPF MVVM入门系列教程(五、命令和用户输入)

&#x1f9ed; WPF MVVM入门系列教程 一、MVVM模式介绍二、依赖属性三、数据绑定四、ViewModel五、命令和用户输入六、ViewModel案例演示 WPF中的命令模型 在WPF中&#xff0c;我们可以使用事件来响应鼠标和键盘动作。 但使用事件会具备一定的局限性&#xff0c;例如&#x…

2025年01月09日德美医疗前端面试

目录 vue2 的双向绑定的原理vue3 的双向绑定原理vue 的生命周期vue 子组件为何不能修改父组件的值js delete 删除数组的某一个值会怎么样vue 和 react 的 diff 算法什么是闭包原型链this指向 vue2 的双向绑定的原理 以下是 Vue 2 双向绑定的原理&#xff1a; 1. 核心概念 …

知识图谱 + 大语言模型:打造更聪明、更可靠的AI大脑 —— 探索 GraphRAG 中文优化与可视化实践

大语言模型&#xff08;LLMs&#xff09;无疑是近年来人工智能领域最耀眼的明星。它们强大的自然语言理解和生成能力&#xff0c;在文本创作、代码生成、对话交互等众多领域展现了惊人的潜力。然而&#xff0c;当前的 LLMs 并非完美无缺&#xff0c;它们常常面临着“幻觉”&…

【uniapp】在UniApp中检测手机是否安装了某个应用

1. 使用plus.runtime.isApplicationExist&#xff08;仅限App端&#xff09; // 判断应用是否安装 function checkAppInstalled(packageName) {if (uni.getSystemInfoSync().platform android || uni.getSystemInfoSync().platform ios) {// 仅App端可用if (typeof plus ! u…

使用 Vue + Axios 构建与后端交互的高效接口调用方案

使用 Vue Axios 构建与后端交互的高效接口调用方案 在 Vue 前端开发中&#xff0c;与后端接口的数据交互是非常核心的部分。而 Axios 是 Vue 项目中最常用的 HTTP 客户端&#xff0c;具备基于 Promise、拦截器、自定义实例等诸多优势。 本篇将深入介绍如何基于 Vue 搭配 Axi…

RN学习笔记 ✅

太无聊了最近&#xff0c;找点事做&#xff0c;学一下RN丰富一下技术栈&#x1fae1;。但是开发APP除了RN&#xff0c;还有一种选择就是WebView&#xff0c;但是基于WebView的APP的性能被普遍认为不如RN&#xff0c;因为WebView本质上是一个容器&#xff0c;用于在应用中嵌入网…

聊天助手提示词调优案例

一、背景 今天有粉丝说自己的聊天助手提示词输出的效果不好&#xff0c;输出的内容不是太呆板就是太浮夸&#xff0c;希望更像真人一样。 本文介绍几个调优方法&#xff0c;希望对大家有启发。 二、调优 《系统掌握大语言模型提示词 - 从理论到实践》提示词小册中介绍了很多…

5.6 react组件化开发基础

react 组件开发基础 组件分类与组件使用 组件传参 父传子 【函数数据传值 实参 形参对应关系】 子传父 插槽 透传 useContext 上下文&#xff08;作用域&#xff09; 跨层级调用方法 通过子组件的实例对象useRef 直接调用子组件的方法 和数据 状态管理&#xff08;非常多…

【SF顺丰】顺丰开放平台API对接(Java对接篇)

对接前置篇&#xff1a; 【SF顺丰】顺丰开放平台API对接&#xff08;注册、API测试篇&#xff09;_顺丰api接口对接指南-CSDN博客 1.实现效果展示 2.SF顺丰开放平台&#xff0c;JDK资源下载。 下载地址&#xff1a;顺丰开放平台 3.将下载的JDK放入项目中。 4.将JDK资源引入p…

我用cursor 搭建了临时邮箱服务-Temp Mail 365

用业余时间搭建了一个临时邮箱&#xff0c;对于后端程序员出身的我&#xff0c;对前端了解的不太多&#xff0c;有了cursor的帮助&#xff0c;补齐了自己的短板&#xff0c;搭建了这个服务&#xff0c;下面对临时邮箱架构设计与安全性做一个分析。 https://temp-mail-365.com 临…

破解工业3D可视化困局,HOOPS Visualize助力高效跨平台协作与交互!

一、当前3D可视化面临的痛点 &#xff08;1&#xff09;性能瓶颈 现有的许多3D可视化工具在处理大型复杂模型时往往力不从心。例如在航空航天、汽车制造等高端制造业&#xff0c;动辄涉及数以亿计的三角面片和海量的纹理细节。这些超大规模的模型在渲染时常常出现卡顿、延迟&…

1、Kafka与消息队列核心原理详解

消息队列&#xff08;Message Queue, MQ&#xff09;作为现代分布式系统的基础组件&#xff0c;极大提升了系统的解耦、异步处理和削峰能力。本文以Kafka为例&#xff0c;系统梳理消息队列的核心原理、架构细节及实际应用。 Kafka 基础架构及术语关系图 术语简要说明 Produce…

2025年北京市职工职业技能大赛第六届信息通信行业网络安全技能大赛初赛-wp

- -考试当场没做出来 后面做的 misc ❯ cd misc ❯ ls num.docx num.zip ❯ unzip num.docx Archive: num.docxinflating: [Content_Types].xmlinflating: _rels/.relsinflating: word/document.xmlinflating: word/_rels/document.xml.relsextracting: word/media/image1.jp…

JavaScript 到命令和控制 (C2) 服务器恶意软件分析及防御

攻击始于一个经过混淆的JavaScript文件,该文件从开源服务中获取编码字符串以执行PowerShell脚本。然后,该脚本从一个IP地址和一个URL缩短器下载一个JPG图像和一个文本文件,这两个文件都包含使用隐写术嵌入的恶意MZ DOS可执行文件。这些有效载荷一旦执行,就会部署Stealer恶意…

【计网】ipconfig、ping、arp、tracert

目录 ipconfig ping arp tracert cmd ipconfig ipcofig -all IPv4 物理地址 ping 检测网络连通情况&#xff0c;分析网络速度 根据域名得到服务器IP 根据TTL判断对方所使用的操作系统以及数据包经过路由器数量 byte数据包大小 time响应时间 TTLDNS记录在DNS服务器上存在…

WiFi那些事儿(八)——802.11n

目录 802.11n 技术简介与测试项 一、802.11n 技术简介 &#xff08;一&#xff09;标准概述 &#xff08;二&#xff09;关键技术特性 1. MIMO&#xff08;多输入多输出&#xff09;技术 2. 信道绑定&#xff08;Channel Bonding&#xff09; 3. 帧聚合&#xff08;Fram…

码蹄集——直角坐标到极坐标的转换、射线、线段

目录 MT1052 直角坐标到极坐标的转换 MT1066 射线 MT1067 线段 MT1052 直角坐标到极坐标的转换 思路&#xff1a; arctan()在c中是atan()&#xff0c;结果是弧度要转换为度&#xff0c;即乘与180/PI 拓展&#xff1a;cos()、sin()在c代码中表示方式不变 #include<bits/…

深入解析 Linux/Unix 通信机制:从原理到观测实践

深入解析 Linux/Unix 通信机制&#xff1a;从原理到观测实践 配图建议&#xff1a;Linux系统架构与通信机制全景示意图 一、开篇&#xff1a;理解“一切皆文件”的哲学 Unix/Linux 操作系统的核心灵魂在于其独特的设计哲学。当 Dennis Ritchie 和 Ken Thompson 在贝尔实验室开…

spring上传文件添加水印

1、实现 MultipartFile package com.pojo.common.core.domain;import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream;import org.springframework.lang.Nullable; import org.springframework.util.Assert; im…