数据结构图综合实验实验报告宁波工程学院
《数据结构》实验报告模板(附实例)--实验一线性表的基本操作实现
《数据结构》实验报告模板(附实例)---实验一线性表的基本操作实现实验一线性表的基本操作实现及其应用一、实验目的1、熟练掌握线性表的基本操作在两种存储结构上的实现,其中以熟悉各种链表的操作为重点。
2、巩固高级语言程序设计方法与技术,会用线性链表解决简单的实际问题。
二、实验内容√ 1、单链表的表示与操作实现 ( * )2、约瑟夫环问题3、Dr.Kong的艺术品三、实验要求1、按照数据结构实验任务书,提前做好实验预习与准备工作。
2、加“*”题目必做,其他题目任选;多选者并且保质保量完成适当加分。
3、严格按照数据结构实验报告模板和规范,及时完成实验报告。
四、实验步骤(说明:依据实验内容分别说明实验程序中用到的数据类型的定义、主程序的流程以及每个操作(成员函数)的伪码算法、函数实现、程序编码、调试与分析、总结、附流程图与主要代码)㈠、数据结构与核心算法的设计描述(程序中每个模块或函数应加注释,说明函数功能、入口及出口参数)1、单链表的结点类型定义/* 定义DataType为int类型 */typedef int DataType;/* 单链表的结点类型 */typedef struct LNode{ DataType data;struct LNode *next;}LNode,*LinkedList;2、初始化单链表LinkedList LinkedListInit( ){ // 每个模块或函数应加注释,说明函数功能、入口及出口参数 }3、清空单链表void LinkedListClear(LinkedList L){// 每个模块或函数应加注释,说明函数功能、入口及出口参数}4、检查单链表是否为空int LinkedListEmpty(LinkedList L){ …. }5、遍历单链表void LinkedListTraverse(LinkedList L){….}6、求单链表的长度int LinkedListLength(LinkedList L){ …. }7、从单链表表中查找元素LinkedList LinkedListGet(LinkedList L,int i){ //L是带头结点的链表的头指针,返回第 i 个元素 }8、从单链表表中查找与给定元素值相同的元素在链表中的位置LinkedList LinkedListLocate(LinkedList L, DataType x){ …… }9、向单链表中插入元素void LinkedListInsert(LinkedList L,int i,DataType x) { // L 为带头结点的单链表的头指针,本算法// 在链表中第i 个结点之前插入新的元素 x}10、从单链表中删除元素void LinkedListDel(LinkedList L,DataType x){ // 删除以 L 为头指针的单链表中第 i 个结点 }11、用尾插法建立单链表LinkedList LinkedListCreat( ){ …… }㈡、函数调用及主函数设计(可用函数的调用关系图说明)㈢程序调试及运行结果分析㈣实验总结五、主要算法流程图及程序清单1、主要算法流程图:2、程序清单(程序过长,可附主要部分)说明:以后每次实验报告均按此格式书写。
数据结构实验报告--图
数据结构实验报告--图
数据结构实验报告--图
1、实验目的
本实验主要旨在通过实践操作,深入理解图这种数据结构的基本概念、性质和基本操作,掌握图的存储结构与常见算法。
2、实验环境
本次实验使用编程语言C++,在Windows平台下进行开发和运行。
3、实验内容
3.1 图的定义与基本概念
在本章中,我们将介绍图的基本概念,包括有向图与无向图、顶点与边、度与入度出度、连通性等。
3.2 图的存储结构
在本章中,我们将介绍图的几种存储结构,包括邻接矩阵、邻接表和十字链表,以及它们的优缺点和适用场景。
3.3 图的遍历
在本章中,我们将介绍图的两种常用的遍历算法,即深度优先搜索(DFS)和广度优先搜索(BFS),并分别给出它们的实现代码和应用场景。
3.4 最短路径
在本章中,我们将介绍图的最短路径问题,包括单源最短路径和全源最短路径。
我们将使用Dijkstra算法和Floyd-Warshall算法来解决这些问题,并给出它们的实现代码和应用场景。
3.5 最小树
在本章中,我们将介绍图的最小树问题,即找到一棵树使得树上的边的权值之和最小。
我们将使用Prim算法和Kruskal算法来解决这个问题,并给出它们的实现代码和应用场景。
4、实验步骤和结果
在本章中,我们将详细介绍实验的具体步骤,并给出实验结果的详细分析和说明。
5、实验总结
在本章中,我们将对整个实验进行总结,总结实验中遇到的问题、解决方案和经验教训。
6、附件
本实验报告所涉及的附件包括实验代码和运行结果的截图。
7、法律名词及注释
本文所涉及的法律名词和注释详见附件中的相关文件。
数据结构实训实验报告
一、实验背景数据结构是计算机科学中一个重要的基础学科,它研究如何有效地组织和存储数据,并实现对数据的检索、插入、删除等操作。
为了更好地理解数据结构的概念和原理,我们进行了一次数据结构实训实验,通过实际操作来加深对数据结构的认识。
二、实验目的1. 掌握常见数据结构(如线性表、栈、队列、树、图等)的定义、特点及操作方法。
2. 熟练运用数据结构解决实际问题,提高算法设计能力。
3. 培养团队合作精神,提高实验报告撰写能力。
三、实验内容本次实验主要包括以下内容:1. 线性表(1)实现线性表的顺序存储和链式存储。
(2)实现线性表的插入、删除、查找等操作。
2. 栈与队列(1)实现栈的顺序存储和链式存储。
(2)实现栈的入栈、出栈、判断栈空等操作。
(3)实现队列的顺序存储和链式存储。
(4)实现队列的入队、出队、判断队空等操作。
3. 树与图(1)实现二叉树的顺序存储和链式存储。
(2)实现二叉树的遍历、查找、插入、删除等操作。
(3)实现图的邻接矩阵和邻接表存储。
(4)实现图的深度优先遍历和广度优先遍历。
4. 算法设计与应用(1)实现冒泡排序、选择排序、插入排序等基本排序算法。
(2)实现二分查找算法。
(3)设计并实现一个简单的学生成绩管理系统。
四、实验步骤1. 熟悉实验要求,明确实验目的和内容。
2. 编写代码实现实验内容,对每个数据结构进行测试。
3. 对实验结果进行分析,总结实验过程中的问题和经验。
4. 撰写实验报告,包括实验目的、内容、步骤、结果分析等。
五、实验结果与分析1. 线性表(1)顺序存储的线性表实现简单,但插入和删除操作效率较低。
(2)链式存储的线性表插入和删除操作效率较高,但存储空间占用较大。
2. 栈与队列(1)栈和队列的顺序存储和链式存储实现简单,但顺序存储空间利用率较低。
(2)栈和队列的入栈、出队、判断空等操作实现简单,但需要考虑数据结构的边界条件。
3. 树与图(1)二叉树和图的存储结构实现复杂,但能够有效地表示和处理数据。
数据结构图实验报告
数据结构图实验报告数据结构图实验报告1. 引言数据结构是计算机科学中的重要概念之一,它研究数据的组织、存储和管理方式。
图作为一种重要的数据结构,广泛应用于各个领域,如网络拓扑、社交网络分析等。
本实验旨在通过实际操作,深入理解数据结构图的基本概念和操作。
2. 实验目的本实验的主要目的是掌握图的基本概念和相关操作,包括图的创建、遍历、搜索和最短路径算法等。
3. 实验环境本实验使用C++语言进行编程,采用图的邻接矩阵表示法进行实现。
4. 实验内容4.1 图的创建在实验中,我们首先需要创建一个图。
通过读取输入文件中的数据,我们可以获得图的顶点数和边数,并根据这些信息创建一个空的图。
4.2 图的遍历图的遍历是指从图的某个顶点出发,按照一定的规则依次访问图中的其他顶点。
常用的图的遍历算法有深度优先搜索(DFS)和广度优先搜索(BFS)。
我们可以通过实验来比较这两种遍历算法的效率和应用场景。
4.3 图的搜索图的搜索是指从图的某个顶点出发,找到与之相关的特定顶点或边。
常用的图的搜索算法有深度优先搜索和广度优先搜索。
在实验中,我们可以通过输入特定的顶点或边,来观察图的搜索算法的执行过程和结果。
4.4 图的最短路径算法图的最短路径算法是指在图中找到两个顶点之间的最短路径。
常用的最短路径算法有迪杰斯特拉算法和弗洛伊德算法。
通过实验,我们可以比较这两种算法的执行效率和应用场景。
5. 实验结果与分析通过实验,我们可以得到以下结论:- 图的邻接矩阵表示法在创建和操作图的过程中具有较高的效率。
- 深度优先搜索算法适用于查找图中的连通分量和回路等问题。
- 广度优先搜索算法适用于查找图中的最短路径和最小生成树等问题。
- 迪杰斯特拉算法适用于求解单源最短路径问题,而弗洛伊德算法适用于求解多源最短路径问题。
6. 实验总结通过本次实验,我们深入学习了数据结构图的基本概念和相关操作。
图作为一种重要的数据结构,具有广泛的应用价值。
在今后的学习和工作中,我们可以运用所学的知识,解决实际问题,提高工作效率。
数据结构图综合实验实验报告宁波工程学院
数据结构图综合实验实验报告宁波工程学院图综合实验实验报告一、实验目的1)熟悉图的基本操作。
2)掌握求图的最短路径算法。
3)加深对图的理解,逐步培养解决实际问题的编程能力。
班级:计科12-1 学号:124010101姓名:实验日期:二、实验环境装有Visual C++的计算机。
本次实验共计4学时。
三、实验内容【基本要求】给定n个村庄之间的交通图。
若村庄i和j之间有路可通,则i和j用边连接,边上的权值Wij表示这条道路的长度。
现打算在这n个村庄中选定一个村庄建一所医院。
编写如下算法:求出该医院应建在哪个村庄,才能使距离医院最远的村庄到医院的路程最短。
求出该医院应建在哪个村庄,能使其它所有村庄到医院的路径总和最短。
【提示】? 对于问题,可以先求出每个村庄到其它所有村庄的最短路径,保存其最大值;然后在这些最大值中找出一个最小值。
? 对于问题,可以先求出每个村庄到其它所有村庄的最短路径,保存其累加和;然后在这些和中找出一个最小值。
? 自己设定n个村庄的交通图。
例如下图所示:四、重要数据结构typedef struct/*图的定义*/ { int edges[MAXV][MAXV]; /*邻接矩阵*/ int n,e;/*顶点数,弧数*/ } MGraph;/*图的邻接矩阵类型*/ 五、实现思路分析void Dijkstra(MGraph g,int v); //狄克斯特拉算法void Dispath(int dist,int path,int s,int n,int v); void Ppath(int path,int i,int v); void He(MGraph g,int v);//情况一void Slove(MGraph g,int v);//情况二六、程序调试问题分析狄克斯特拉算法输出的dist【i】总为0,在主函数对[i][j]先赋值即可。
七、实验总结通过这次实验,我对最小生成树有了更好的认识。
数据结构实验报告
数据结构实验报告一、实验目的本实验旨在通过对数据结构的学习和实践,掌握基本的数据结构概念、原理及其应用,培养学生的问题分析与解决能力,提升编程实践能力。
二、实验背景数据结构是计算机科学中的重要基础,它研究数据的存储方式和组织形式,以及数据之间的关系和操作方法。
在软件开发过程中,合理选用和使用数据结构,能够提高算法效率,优化内存利用,提升软件系统的性能和稳定性。
三、实验内容本次实验主要涉及以下几个方面的内容:1.线性表的基本操作:包括线性表的创建、插入、删除、查找、修改等操作。
通过编程实现不同线性表的操作,掌握它们的原理和实现方法。
2.栈和队列的应用:栈和队列是常用的数据结构,通过实现栈和队列的基本操作,学会如何解决实际问题。
例如,利用栈实现括号匹配,利用队列实现银行排队等。
3.递归和回溯算法:递归和回溯是解决很多求解问题的常用方法。
通过编程实现递归和回溯算法,理解它们的思想和应用场景。
4.树和二叉树的遍历:学习树和二叉树的遍历方法,包括前序、中序和后序遍历。
通过编程实现这些遍历算法,加深对树结构的理解。
5.图的基本算法:学习图的基本存储结构和算法,包括图的遍历、最短路径、最小生成树等。
通过编程实现这些算法,掌握图的基本操作和应用。
四、实验过程1.具体实验内容安排:根据实验要求,准备好所需的编程环境和工具。
根据实验要求逐步完成实验任务,注意记录并整理实验过程中遇到的问题和解决方法。
2.实验数据采集和处理:对于每个实验任务,根据要求采集并整理测试数据,进行相应的数据处理和分析。
记录实验过程中的数据和结果。
3.实验结果展示和分析:将实验结果进行适当的展示,例如表格、图形等形式,分析实验结果的特点和规律。
4.实验总结与反思:总结实验过程和结果,回顾实验中的收获和不足,提出改进意见和建议。
五、实验结果与分析根据实验步骤和要求完成实验任务后,得到了相应的实验结果。
对于每个实验任务,根据实验结果进行适当的分析。
数据结构实验报告及心得体会
数据结构实验报告及心得体会一、概述:介绍本次实验的目的、背景以及所使用的实验环境和工具。
本次实验旨在通过实际操作,深入理解和掌握数据结构的原理及应用。
实验背景源于课程学习的理论知识与实际应用相结合的需求,通过实验操作,期望能够将课堂所学的数据结构知识更好地运用到实际编程和解决现实问题中。
本次实验所使用的实验环境为先进的计算机实验室,配备了高性能的计算机硬件和丰富的软件开发工具。
为了完成实验,我使用了Java编程语言,并结合Eclipse开发环境进行编程和调试。
我还参考了相关的数据结构专业书籍和在线资源,以便更好地理解和应用数据结构知识。
在实验过程中,我严格按照实验指导书的步骤进行操作,并认真记录了实验数据和结果。
通过本次实验,我深刻体会到了数据结构的重要性,也对数据结构的实现和应用有了更深入的了解。
二、实验内容:分别介绍线性数据结构(线性表)、非线性数据结构(二叉树、图)的实验内容,包括其实现方法、操作过程等。
每个实验都包含具体的实验目的和预期结果。
三、实验过程及结果分析:详细描述实验过程,包括实验步骤的执行情况,遇到的问题及解决方法。
对实验结果进行展示,并进行数据分析和结论。
这部分是实验报告的核心部分,体现了学生的实践能力和问题解决能力。
四、心得体会:分享在实验过程中的心得体会,包括遇到的困难、收获,对数据结构的理解与认识提升,以及实验过程中的团队协作和学习体验等。
这部分内容可以体现出学生的思考深度和学习的主观感受。
五、总结与展望:对本次实验报告进行总结,并对未来数据结构与算法的学习提出展望和建议。
这部分内容可以帮助学生梳理所学知识,明确未来的学习方向。
数据结构实验实训总结报告
一、实验背景随着计算机技术的飞速发展,数据结构作为计算机科学的重要基础,已经成为现代软件开发和数据处理的关键技术。
为了提高学生的数据结构应用能力,我们学校开设了数据结构实验实训课程。
本课程旨在通过实验实训,使学生深入理解数据结构的基本概念、性质、应用,掌握各种数据结构的实现方法,提高编程能力和解决实际问题的能力。
二、实验内容本次数据结构实验实训主要包括以下内容:1. 数据结构的基本概念和性质通过实验,使学生掌握线性表、栈、队列、串、树、图等基本数据结构的概念、性质和应用场景。
2. 数据结构的存储结构通过实验,使学生熟悉线性表、栈、队列、串、树、图等数据结构的顺序存储和链式存储方法,了解不同存储结构的优缺点。
3. 数据结构的操作算法通过实验,使学生掌握线性表、栈、队列、串、树、图等数据结构的插入、删除、查找、遍历等基本操作算法。
4. 数据结构的实际应用通过实验,使学生了解数据结构在各个领域的应用,如网络数据结构、数据库数据结构、人工智能数据结构等。
三、实验过程1. 实验准备在实验开始前,教师首先对实验内容进行讲解,使学生了解实验目的、实验步骤和实验要求。
同时,教师要求学生预习实验内容,熟悉相关理论知识。
2. 实验实施(1)线性表:通过实现线性表的顺序存储和链式存储,实现插入、删除、查找等操作。
(2)栈和队列:通过实现栈和队列的顺序存储和链式存储,实现入栈、出栈、入队、出队等操作。
(3)串:通过实现串的顺序存储和链式存储,实现串的插入、删除、查找等操作。
(4)树:通过实现二叉树、二叉搜索树、平衡二叉树等,实现树的插入、删除、查找、遍历等操作。
(5)图:通过实现图的邻接矩阵和邻接表存储,实现图的插入、删除、查找、遍历等操作。
3. 实验总结实验结束后,教师组织学生进行实验总结,总结实验过程中的收获和不足,提出改进措施。
四、实验成果通过本次数据结构实验实训,学生取得了以下成果:1. 掌握了数据结构的基本概念、性质和应用场景。
数据结构 图实验报告
数据结构图实验报告数据结构图实验报告引言:数据结构是计算机科学中非常重要的一个概念,它用于存储和组织数据,使得数据的操作更加高效和方便。
图是一种常见的数据结构,它由节点和边组成,用于表示各种实际问题中的关系和连接。
本实验旨在通过实际操作,深入理解图的基本概念和常见操作。
实验目的:1. 理解图的基本概念和特性;2. 掌握图的存储结构和基本操作;3. 实现图的遍历算法;4. 分析图的应用场景。
实验过程:1. 图的存储结构:在本次实验中,我们选择邻接矩阵来存储图。
邻接矩阵是一个二维数组,其中行和列分别表示图中的节点,数组元素表示节点之间的边的关系。
具体而言,如果节点i和节点j之间存在边,则邻接矩阵中的第i行第j列元素为1;否则为0。
2. 图的基本操作:在实验中,我们实现了以下几个图的基本操作:- 添加节点:通过向邻接矩阵中添加一行一列,并设置对应的边的关系,来添加一个节点;- 添加边:通过修改邻接矩阵中对应元素的值,来添加一条边;- 删除节点:通过删除邻接矩阵中对应行和列,并更新其他节点的索引,来删除一个节点;- 删除边:通过修改邻接矩阵中对应元素的值,来删除一条边;- 查找节点:通过遍历邻接矩阵,找到对应节点的索引;- 查找边:通过遍历邻接矩阵,找到对应边的关系。
3. 图的遍历算法:在实验中,我们实现了深度优先搜索(DFS)和广度优先搜索(BFS)两种图的遍历算法。
DFS通过递归的方式,先访问当前节点,再依次访问相邻节点,直到所有节点都被访问。
BFS则通过队列的方式,先访问当前节点,再依次访问当前节点的相邻节点,直到所有节点都被访问。
实验结果:通过实验,我们成功实现了图的存储结构和基本操作,并且正确实现了DFS和BFS两种遍历算法。
我们对不同规模的图进行了测试,并分析了算法的时间复杂度。
实验结果表明,邻接矩阵的存储结构在添加和删除节点时的时间复杂度较高,而在查找节点和边时的时间复杂度较低。
DFS和BFS的时间复杂度都为O(V+E),其中V表示节点数,E表示边数。
数据结构课程实验报告
数据结构课程实验报告一、实验目的本次数据结构课程实验的主要目的是通过实践掌握常见数据结构的基本操作,包括线性结构、树形结构和图形结构。
同时,也要求学生能够熟练运用C++语言编写程序,并且能够正确地使用各种算法和数据结构解决具体问题。
二、实验内容本次实验涉及到以下几个方面:1. 线性表:设计一个线性表类,并且实现线性表中元素的插入、删除、查找等基本操作。
2. 栈和队列:设计一个栈类和队列类,并且分别利用这两种数据结构解决具体问题。
3. 二叉树:设计一个二叉树类,并且实现二叉树的遍历(前序遍历、中序遍历和后序遍历)。
4. 图论:设计一个图类,并且利用图论算法解决具体问题(如最短路径问题)。
三、实验过程1. 线性表首先,我们需要设计一个线性表类。
在这个类中,我们需要定义一些成员变量(如线性表大小、元素类型等),并且定义一些成员函数(如插入元素函数、删除元素函数等)。
在编写代码时,我们需要注意一些细节问题,如边界条件、异常处理等。
2. 栈和队列接下来,我们需要设计一个栈类和队列类。
在这两个类中,我们需要定义一些成员变量(如栈顶指针、队头指针等),并且定义一些成员函数(如入栈函数、出栈函数、入队函数、出队函数等)。
在编写代码时,我们需要注意一些细节问题,如空间不足的情况、空栈或空队列的情况等。
3. 二叉树然后,我们需要设计一个二叉树类,并且实现二叉树的遍历。
在这个类中,我们需要定义一个节点结构体,并且定义一些成员变量(如根节点指针、节点数量等),并且定义一些成员函数(如插入节点函数、删除节点函数、遍历函数等)。
在编写代码时,我们需要注意一些细节问题,如递归调用的情况、空节点的情况等。
4. 图论最后,我们需要设计一个图类,并且利用图论算法解决具体问题。
在这个类中,我们需要定义一个邻接矩阵或邻接表来表示图形结构,并且定义一些成员变量(如顶点数量、边的数量等),并且定义一些成员函数(如添加边函数、删除边函数、最短路径算法等)。
数据结构实验报告--图
.数据结构实验报告图一、实验目的1、熟悉图的结构和相关算法。
二、实验内容及要求1、编写创建图的算法。
2、编写图的广度优先遍历、深度优先遍历、及求两点的简单路径和最短路径的算法。
三、算法描述1、图的邻接表存储表示:对图的每个顶点建立一个单链表,第i个单链表表示所有依附于第i个点的边(对于有向图表示以该顶点为尾的弧);链表的每个节点存储两个信息,该弧指向的顶点在图中的位置(adjvex)和指向下一条弧的指针(nextarc)。
每个连表的头结点存储顶点的数据:顶点信息(data)和指向依附于它的弧的链表域。
存储表示如下:typedef struct ArcNode {int adjvex; // 该弧所指向的顶点的位置struct ArcNode *nextarc;// 指向下一条弧的指针// InfoType *info; // 该弧相关信息的指针} ArcNode;typedef struct VNode {char data; // 顶点信息int data2;int sngle;ArcNode *firstarc;// 指向第一条依附该顶点的弧} VNode, AdjList[MAX_NUM];typedef struct {AdjList vertices;int vexnum, arcnum;int kind; // 图的种类标志} ALGraph;2、深度优先搜索:假设初始态是图中所有定点未被访问,从图中的某个顶点v开始,访问此顶点,然后依次从v的未访问的邻接点出发深度优先遍历,直至途中所有和v有相同路径的点都被访问到;若图中仍有点未被访问,则从图中另选一个未被访问的点作为起点重复上述过程,直到图中所有点都被访问到。
为了便于区分途中定点是否被访问过,需要附设一个访问标致数组visited [0..n-1],将其初值均设为false,一旦某个顶点被访问,将对应的访问标志赋值为true。
2、广度优先搜索:假设初始态是图中所有顶点未被访问,从图中的某个顶点v开始依次访问v的各个未被访问的邻接点,然后分别从这些邻接点出发以此访问他们的邻接点,并使“先被访问的邻接顶点”先于“后被访问的邻接顶点”被访问,直至图中所有已被访问过的顶点的邻接顶点都被访问。
数据结构课程实验报告
数据结构课程实验报告目录1. 实验简介1.1 实验背景1.2 实验目的1.3 实验内容2. 实验方法2.1 数据结构选择2.2 算法设计2.3 程序实现3. 实验结果分析3.1 数据结构性能分析3.2 算法效率比较3.3 实验结论4. 实验总结1. 实验简介1.1 实验背景本实验是数据结构课程的一次实践性操作,旨在帮助学生加深对数据结构的理解和运用。
1.2 实验目的通过本实验,学生将学会如何选择合适的数据结构来解决特定问题,了解数据结构与算法设计的关系并能将其应用到实际问题中。
1.3 实验内容本实验将涉及对一些经典数据结构的使用,如链表、栈、队列等,并结合具体问题进行算法设计和实现。
2. 实验方法2.1 数据结构选择在实验过程中,需要根据具体问题选择合适的数据结构,比如针对需要频繁插入删除操作的情况可选择链表。
2.2 算法设计针对每个问题,需要设计相应的算法来实现功能,要考虑算法的效率和实际应用情况。
2.3 程序实现根据算法设计,编写相应的程序来实现功能,并进行调试测试确保程序能够正确运行。
3. 实验结果分析3.1 数据结构性能分析在实验过程中,可以通过对不同数据结构的使用进行性能分析,如时间复杂度和空间复杂度等,以便选择最优的数据结构。
3.2 算法效率比较实验完成后,可以对不同算法在同一数据结构下的效率进行比较分析,找出最优算法。
3.3 实验结论根据实验结果分析,得出结论并总结经验教训,为后续的数据结构和算法设计提供参考。
4. 实验总结通过本次实验,学生将对数据结构与算法设计有更深入的了解,并能将所学知识应用到实际问题中,提高自己的实践能力和解决问题的能力。
数据结构实验报告 图
数据结构实验报告图一、实验目的本次实验的主要目的是深入理解和掌握图这种数据结构的基本概念、存储结构和相关算法,并通过实际编程实现来提高对图的操作和应用能力。
二、实验环境本次实验使用的编程语言为C++,开发工具为Visual Studio 2019。
三、实验内容(一)图的存储结构1、邻接矩阵邻接矩阵是用一个二维数组来表示图中顶点之间的关系。
如果顶点i 和顶点 j 之间有边相连,则数组中对应的元素值为 1;否则为 0。
这种存储结构简单直观,适用于顶点数较少且边数较多的稠密图。
2、邻接表邻接表是为图的每个顶点建立一个单链表,链表中存储的是与该顶点相邻的顶点信息。
这种存储结构在存储空间上比较节省,适用于顶点数较多且边数较少的稀疏图。
(二)图的遍历算法1、深度优先遍历(DepthFirst Search,简称 DFS)从图中的某个顶点出发,沿着一条路径尽可能深地访问顶点,直到无法继续前进,然后回溯到上一个未完全访问的顶点,继续进行深度优先搜索。
2、广度优先遍历(BreadthFirst Search,简称 BFS)从图中的某个顶点出发,先访问其所有相邻的顶点,然后再依次访问这些相邻顶点的相邻顶点,以此类推,逐层向外扩展。
(三)图的最短路径算法1、迪杰斯特拉(Dijkstra)算法用于求解单源最短路径问题,即从一个给定的源顶点到图中其他所有顶点的最短路径。
2、弗洛伊德(Floyd)算法用于求解任意两个顶点之间的最短路径。
四、实验步骤(一)邻接矩阵的实现```cppinclude <iostream>using namespace std;const int MAX_VERTEX_NUM = 100;class Graph {private:int vertexNum;int edgeNum;int adjMatrixMAX_VERTEX_NUMMAX_VERTEX_NUM;public:Graph(int vNum) {vertexNum = vNum;edgeNum = 0;for (int i = 0; i < vertexNum; i++){for (int j = 0; j < vertexNum; j++){adjMatrixij = 0;}}}void addEdge(int i, int j) {if (i >= 0 && i < vertexNum && j >= 0 && j < vertexNum) {adjMatrixij = 1;adjMatrixji = 1;edgeNum++;}}void printGraph(){for (int i = 0; i < vertexNum; i++){for (int j = 0; j < vertexNum; j++){cout << adjMatrixij <<"";}cout << endl;}}};int main(){Graph g(5);gaddEdge(0, 1);gaddEdge(0, 2);gaddEdge(1, 2);gaddEdge(2, 3);gaddEdge(3, 4);gprintGraph();return 0;}```(二)邻接表的实现```cppinclude <iostream>include <vector>using namespace std;const int MAX_VERTEX_NUM = 100; class Graph {private:int vertexNum;vector<int> adjListMAX_VERTEX_NUM;public:Graph(int vNum) {vertexNum = vNum;}void addEdge(int i, int j) {if (i >= 0 && i < vertexNum && j >= 0 && j < vertexNum) {adjListipush_back(j);adjListjpush_back(i);}}void printGraph(){for (int i = 0; i < vertexNum; i++){cout << i <<":";for (int j = 0; j < adjListisize(); j++){cout << adjListij <<"";}cout << endl;}}};int main(){Graph g(5);gaddEdge(0, 1);gaddEdge(0, 2);gaddEdge(1, 2);gaddEdge(2, 3);gaddEdge(3, 4);gprintGraph();return 0;}```(三)深度优先遍历的实现```cppinclude <iostream>include <vector>using namespace std;const int MAX_VERTEX_NUM = 100;class Graph {private:int vertexNum;vector<int> adjListMAX_VERTEX_NUM;bool visitedMAX_VERTEX_NUM;public:Graph(int vNum) {vertexNum = vNum;for (int i = 0; i < vertexNum; i++){visitedi = false;}}void addEdge(int i, int j) {if (i >= 0 && i < vertexNum && j >= 0 && j < vertexNum) {adjListipush_back(j);adjListjpush_back(i);}}void DFS(int v) {visitedv = true;cout << v <<"";for (int i = 0; i < adjListvsize(); i++){int u = adjListvi;if (!visitedu) {DFS(u);}}}void DFSTraversal(){for (int v = 0; v < vertexNum; v++){if (!visitedv) {DFS(v);}}}};int main(){Graph g(5);gaddEdge(0, 1);gaddEdge(0, 2);gaddEdge(1, 2);gaddEdge(2, 3);gaddEdge(3, 4);gDFSTraversal();return 0;}```(四)广度优先遍历的实现```cppinclude <iostream>include <queue>include <vector>using namespace std;const int MAX_VERTEX_NUM = 100; class Graph {private:int vertexNum;vector<int> adjListMAX_VERTEX_NUM; bool visitedMAX_VERTEX_NUM; public:Graph(int vNum) {vertexNum = vNum;for (int i = 0; i < vertexNum; i++){visitedi = false;}}void addEdge(int i, int j) {if (i >= 0 && i < vertexNum && j >= 0 && j < vertexNum) {adjListipush_back(j);adjListjpush_back(i);}}void BFS(int v) {queue<int> q;visitedv = true;qpush(v);while (!qempty()){int u = qfront();qpop();cout << u <<"";for (int i = 0; i < adjListusize(); i++){int w = adjListui;if (!visitedw) {visitedw = true;qpush(w);}}}}void BFSTraversal(){for (int v = 0; v < vertexNum; v++){if (!visitedv) {BFS(v);}}}};int main(){Graph g(5);gaddEdge(0, 1);gaddEdge(0, 2);gaddEdge(1, 2);gaddEdge(2, 3);gaddEdge(3, 4);gBFSTraversal();return 0;}```(五)迪杰斯特拉算法的实现```cppinclude <iostream>include <climits>include <vector>using namespace std;const int MAX_VERTEX_NUM = 100; const int INFINITY = INT_MAX; class Graph {private:int vertexNum;int adjMatrixMAX_VERTEX_NUMMAX_VERTEX_NUM;int distanceMAX_VERTEX_NUM;bool visitedMAX_VERTEX_NUM;public:Graph(int vNum) {vertexNum = vNum;for (int i = 0; i < vertexNum; i++){for (int j = 0; j < vertexNum; j++){adjMatrixij = INFINITY;}distancei = INFINITY;visitedi = false;}}void addEdge(int i, int j, int weight) {if (i >= 0 && i < vertexNum && j >= 0 && j < vertexNum) {adjMatrixij = weight;adjMatrixji = weight;}}int minDistance(){int min = INFINITY;int minIndex =-1;for (int v = 0; v < vertexNum; v++){if (!visitedv && distancev <= min) {min = distancev;minIndex = v;}}return minIndex;}void dijkstra(int src) {distancesrc = 0;for (int count = 0; count < vertexNum 1; count++){int u = minDistance();visitedu = true;for (int v = 0; v < vertexNum; v++){if (!visitedv && adjMatrixuv!= INFINITY && distanceu!=INFINITY && distanceu + adjMatrixuv < distancev) {distancev = distanceu + adjMatrixuv;}}}for (int i = 0; i < vertexNum; i++){cout <<"源点"<< src <<"到顶点"<< i <<"的最短距离为: "<< distancei << endl;}}};int main(){Graph g(5);gaddEdge(0, 1, 2);gaddEdge(0, 2, 4);gaddEdge(1, 2, 1);gaddEdge(1, 3, 7);gaddEdge(2, 3, 3);gaddEdge(3, 4, 5);gdijkstra(0);return 0;}```(六)弗洛伊德算法的实现```cppinclude <iostream>include <climits>using namespace std;const int MAX_VERTEX_NUM = 100; const int INFINITY = INT_MAX; class Graph {private:int vertexNum;int adjMatrixMAX_VERTEX_NUMMAX_VERTEX_NUM;int distanceMAX_VERTEX_NUMMAX_VERTEX_NUM;public:Graph(int vNum) {vertexNum = vNum;for (int i = 0; i < vertexNum; i++){for (int j = 0; j < vertexNum; j++){adjMatrixij = INFINITY;}}}void addEdge(int i, int j, int weight) {if (i >= 0 && i < vertexNum && j >= 0 && j < vertexNum) {adjMatrixij = weight;}}void floyd(){for (int i = 0; i < vertexNum; i++){for (int j = 0; j < vertexNum; j++){distanceij = adjMatrixij;}}for (int k = 0; k < vertexNum; k++){for (int i = 0; i < vertexNum; i++){for (int j = 0; j < vertexNum; j++){if (distanceik!= INFINITY && distancekj!= INFINITY &&distanceik + distancekj < distanceij) {distanceij = distanceik + distancekj;}}}}for (int i = 0; i < vertexNum; i++){for (int j = 0; j < vertexNum; j++){if (distanceij == INFINITY) {cout <<"顶点"<< i <<"到顶点"<< j <<"的距离为: 无穷大" << endl;} else {cout <<"顶点"<< i <<"到顶点"<< j <<"的距离为: "<< distanceij << endl;}}}}};int main(){Graph g(4);gaddEdge(0, 1, 5);gaddEdge(0, 3, 10);gaddEdge(1, 2, 3);gaddEdge(2, 3, 1);gfloyd();return 0;}```五、实验结果分析(一)邻接矩阵和邻接表的比较邻接矩阵的优点是可以快速判断两个顶点之间是否有边相连,时间复杂度为O(1)。
数据结构图实验报告
数据结构图实验报告一、实验目的本次实验的主要目的是深入理解和掌握数据结构图的基本概念、原理和操作方法,通过实际编程和操作,提高对数据结构的应用能力和解决问题的能力。
二、实验环境本次实验使用的编程语言为C++,开发环境为Visual Studio 2019。
三、实验内容(一)线性表1、顺序表实现顺序表的创建、插入、删除、查找等基本操作。
分析顺序表在不同操作下的时间复杂度。
2、链表实现单链表、双向链表的创建、插入、删除、查找等基本操作。
比较单链表和双向链表在操作上的优缺点。
(二)栈和队列1、栈实现顺序栈和链式栈。
用栈解决表达式求值问题。
2、队列实现顺序队列和链式队列。
用队列模拟银行排队问题。
(三)树1、二叉树实现二叉树的创建、遍历(前序、中序、后序)。
计算二叉树的深度和节点数。
2、二叉搜索树实现二叉搜索树的插入、删除、查找操作。
分析二叉搜索树的性能。
(四)图1、图的存储实现邻接矩阵和邻接表两种图的存储方式。
比较两种存储方式的优缺点。
2、图的遍历实现深度优先遍历和广度优先遍历算法。
用图的遍历解决最短路径问题。
四、实验步骤(一)线性表1、顺序表定义一个数组来存储顺序表的元素,并使用一个变量记录当前表的长度。
插入操作时,需要判断插入位置是否合法,如果合法则将插入位置后的元素依次向后移动一位,然后将新元素插入指定位置。
删除操作时,先判断删除位置是否合法,合法则将删除位置后的元素依次向前移动一位,并更新表的长度。
查找操作通过遍历数组来实现。
分析不同操作的时间复杂度,插入和删除操作在最坏情况下为O(n),查找操作在平均情况下为 O(n/2)。
2、链表对于单链表,定义一个节点结构体,包含数据域和指向下一个节点的指针域。
通过操作指针来实现插入、删除和查找操作。
双向链表则在节点结构体中增加指向前一个节点的指针,使得操作更加灵活,但也增加了空间复杂度。
比较单链表和双向链表在插入、删除操作中指针的调整过程,得出双向链表在某些情况下更方便,但空间开销较大的结论。
《数据结构》课程综合性实验报告
m=2*n-1;
*ht=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
for(i=1;i<=n;i++)
{ (*ht)[i].weight=w[i];
(*ht)[i].parent=0;
(*ht)[i].lchild=0;
(*ht)[i].rchild=0;
根据给定的n个权值,构造n棵只有根结点的二叉树。在森林中选取两棵根结点权值最小的树作左右子树,构造一棵新的二叉树,置新二叉树根结点权值为其左右子树根结点权值之和。在森林中删除这两棵树,同时将新得到的二叉树加入森林中。重复上述两步,直到只含一棵树为止,这棵树即哈夫曼树。
程序代码:
#include <stdio.h>
(*ht)[s2].parent=i;
(*ht)[i].lchild=s1;
(*ht)[i].rchild=s2;
(*ht)[i].weight=(*ht)[s1].weight+(*ht)[s2].weight;
}
}
void outHftree(HuffmanTree ht,int m)
{
if(m!=0)
}
for(i=n+1;i<=m;i++)
{ (*ht)[i].weight=0;
(*ht)[i].parent=0;
(*ht)[i].lchild=0;
(*ht)[i].rchild=0;
}
for(i=n+1;i<=m;i++)
{
Select(ht,i-1,&s1,&s2);
数据结构综合设计实验报告
实验报告格式1、题目:线性表长整数的加减乘除实现2、完成时间起止2010-12-3-----------2010-12-43、实验要求实现线性表长整数的加减乘除(要求最少一千位以上)4、实验目的通过对长整数加减乘除的实现,深入了解线性表的优势与劣势,同时增强对数据结构实践能力的培养,加强计算机动手能力。
5、实验过程5.1 系统的主控模块流程图#include"File1.cpp"int main(){list a,b,c;init(c);init(a);cout<<"两个数a,b:";create(a);init(b);create(b);cout<<a.a<<"+"<<b.a<<"="; add(a,b,c);display(c);cout<<a.a<<"-"<<b.a<<"="; init(c);thus(a,b,c);display(c);cout<<a.a<<"*"<<b.a<<"="; init(c);multipy(a,b,c);display(c);init(c);cout<<a.a<<"/"<<b.a<<"="; division(a,b,c);display(c);system("pause");}5.2 主要模块流程图首先线性表基本函数#include<iostream>using namespace std;const int maxsize=1000; typedef char elemtype; struct list{elemtype* a;int size;};void init(list& m){m.a=new elemtype[maxsize]; m.size=0;}void create(list& m){cout<<"请输入一个长整数:"; cin>>m.a;m.size=strlen(m.a);}int getsize(list m){return m.size;}bool empty(list m){return m.size==0;}void display(list m){for(int i=0;i<m.size;i++)cout<<m.a[i];cout<<endl;}用于下面计算的基础函数void reverse(list& m){for(int i=0;i<m.size/2;i++) {elemtype t=m.a[i];m.a[i]=m.a[m.size-i-1];m.a[m.size-i-1]=t;}bool compare(list a,list b){if(a.size>=b.size)return true;return false;}void copy(list& a,list b){a.size=b.size;for(int i=0;i<b.size;i++)a.a[i]=b.a[i];a.a[a.size]='\0';}void clearfirst(list& a){ //用来清除数组前面的0 int i=0,k=0;bool t=false;if(a.a[0]!='-'&&a.a[0]!='0')return;else if(a.a[0]=='-') {i=1;t=true;}for(;i<a.size;i++)if(a.a[i]=='0')k++;else break;list b;init(b);copy(b,a);init(a);b.a[b.size]='\0';a.size=b.size-k;if(t==false){ //t为false时,说明a为正for(int tz=0;tz<b.size;tz++)a.a[tz]=b.a[tz+k];}else{a.a[0]='-';for(int tz=0;tz<a.size;tz++)a.a[tz+1]=b.a[k+tz+1];}a.a[a.size]=='\0';}void ch(list& a,int x){ //乘以10 相当于移位for(int i=0;i<x;i++)a.a[a.size+i]='0';a.size=a.size+x;a.a[a.size]=0;}void reverse(list& m){//倒置for(int i=0;i<m.size/2;i++){elemtype t=m.a[i];m.a[i]=m.a[m.size-i-1];m.a[m.size-i-1]=t;}}1大整数加法void add(list a,list b,list& c){ //加法//if(!empty(c)){reverse(c);}reverse(a);reverse(b);int i,k,flag=0,sun;if(compare(a,b)){c.size=a.size;for(i=0;i<b.size;i++){sun=a.a[i]-'0'+b.a[i]-'0'+flag;if(sun>=10){flag=sun/10;sun%=10;}else flag=0;c.a[i]=sun+'0'; }for(i=b.size;i<a.size;i++) {sun=b.a[i]-'0'+flag;if(sun>=10){flag=sun/10;sun%=10;}else flag=0;c.a[i]=sun+'0';}if(flag!=0){c.a[c.size++]='0'+flag;flag=0;}}else{c.size=b.size;for(i=0;i<a.size;i++) {sun=a.a[i]-'0'+b.a[i]-'0'+flag;if(sun>=10){flag=sun/10;sun%=10;} else flag=0;c.a[i]=sun+'0'; }for(i=a.size;i<b.size;i++) {sun=a.a[i]-'0'+flag;if(sun>=10){flag=sun/10;sun%=10;} else flag=0;c.a[i]=sun+'0';}if(flag!=0){c.a[c.size++]='0'+flag;flag=0;} }c.a[c.size]='\0';reverse(a);reverse(b);reverse(c);}减法void thus(list wg,list tg,list& c){ //减法bool zf=true;list a,b; //创建临时a,b 用于操作init(a);init(b);copy(a,wg);copy(b,tg);int i,k,flag=0,sun;if(strlen(a.a)>strlen(b.a)) //大数减小数{reverse(a);reverse(b);for(i=0;i<strlen(b.a);i++){ a.a[i]-=flag/10;if(a.a[i]<b.a[i])flag=10;else flag=0;sun=a.a[i]-b.a[i]+flag+'0';c.a[i]=sun; }for(i=strlen(b.a);i<strlen(a.a);i++){ a.a[i]-=flag/10; flag=0;c.a[i]=a.a[i];}c.size=i;c.a[i]='\0';}else if(strlen(a.a)==strlen(b.a)) //位数相等{int w; bool tf=false;for(w=0;w<a.size;w++)if(a.a[w]<b.a[w]){tf=false; break;}else if(a.a[w]==b.a[w])continue;else {tf=true;break; }reverse(a);reverse(b);if(tf==true&& w<a.size)//if(w>=a.size&&d!=a.size) //位数相等,大数减小数{for(i=0;i<strlen(b.a);i++){ a.a[i]-=flag/10;if(a.a[i]<b.a[i])flag=10;else flag=0;sun=a.a[i]-b.a[i]+flag+'0';c.a[i]=sun; }for(i=strlen(b.a);i<strlen(a.a);i++){ a.a[i]-=flag/10; flag=0;c.a[i]=a.a[i]; }c.size=i;c.a[i]='\0';}else if(w>=a.size){init(c);c.size=1;c.a[0]='0';c.a[c.size]='\0';return;}else //位数相等,小数减大数{for(i=0;i<strlen(a.a);i++){ b.a[i]-=flag/10;if(a.a[i]>b.a[i])flag=10;else flag=0;sun=b.a[i]-a.a[i]+flag+'0';c.a[i]=sun; }for(i=strlen(a.a);i<strlen(b.a);i++){ b.a[i]-=flag/10; flag=0;c.a[i]=b.a[i]; }zf=false;c.size=i;c.a[i]='\0';}}else if(strlen(a.a)<strlen(b.a)) {reverse(a);reverse(b);for(i=0;i<strlen(a.a);i++){ b.a[i]-=flag/10;if(a.a[i]>b.a[i])flag=10;else flag=0;sun=b.a[i]-a.a[i]+flag+'0';c.a[i]=sun; }for(i=strlen(a.a);i<strlen(b.a);i++){ b.a[i]-=flag/10;c.a[i]=b.a[i]; }zf=false;c.size=i;c.a[i]='\0';}reverse(c);if(zf==false){ //符号判断list m;init(m);copy(m,c);init(c); c.size=m.size+1;c.a[0]='-';for(i=0;i<m.size;i++)c.a[i+1]=m.a[i];}c.a[i+1]='\0';clearfirst(c);}void multipy(list wg,list tg,list& c ){ //乘法list a,b; //创建临时a,b 用于操作init(a);init(b);copy(a,wg);copy(b,tg);reverse(a);reverse(b);for(int m=0;m<strlen(a.a)+strlen(b.a);m++)c.a[m]='0';c.size=strlen(a.a)+strlen(b.a);int i,k,sum,flag=0;for(i=0;i<strlen(b.a);++i){if(b.a[i]=='0')continue;sum=0;for(k=0;k<strlen(a.a);++k){sum+=(a.a[k]-'0')*(b.a[i]-'0')+(c.a[k+i]-'0');c.a[k+i]=sum%10+'0'; //进位计算sum/=10;flag=sum;}c.a[strlen(a.a)+i]+=sum;}c.a[c.size]='\0';reverse(a);reverse(b);reverse(c);clearfirst(c);}除法void division(list wg,list tg,list& c){ //除法list a,b; //创建临时a,b 用于操作init(a);init(b);copy(a,wg);copy(b,tg);int i,j; list t,v,k,m;if(empty(b)||empty(a))return;if(strlen(a.a)==strlen(b.a)){ //如果a和b长度相等for(i=0;i<9;i++){ init(k); //thus(a,b,k);if(k.a[0]!='-'){init(a);copy(a,k);continue;}else break;}init(c);c.size=1;c.a[0]=i+'0';c.a[c.size]='\0';}else if(strlen(a.a)<strlen(b.a)){ //如果a比b小init(c);c.size=1;c.a[0]='0';c.a[c.size]='\0';return ;}else if(strlen(a.a)>strlen(b.a)){ //如果a比b大int qwt=strlen(a.a)-strlen(b.a);for(j=0;j<=qwt;j++){init(m);int grf=0;thus(a,b,m);if(m.a[0]=='-')grf++;init(v);copy(v,b);ch(v,qwt-j-grf);for(i=0;i<9;i++){ init(k); //thus(a,v,k);if(k.a[0]!='-'){init(a);copy(a,k);continue;}else break;}c.a[j]=i+'0';c.size++;}if(strlen(a.a)==strlen(b.a)){ for(i=0;i<9;i++){ init(k); //thus(a,b,k);if(k.a[0]!='-'){init(a);copy(a,k);continue;}else break;}if(j<qwt){c.a[c.size]=i+'0';c.size++; }}c.a[c.size]='\0'; }clearfirst(c); }5.3 测试例子测试实例普通加法加法进位等位加法等位减法大数减小数小数减大数小数乘大数大数乘小数大数除小数等位数相同除法高位计算千位级别计算(时间大约1s不到)算法性能优良接上面5.4 设计中碰到的问题,如何解决实验过程中多次碰到数组空间内存溢出的问题,除法运算效率问题,还有计算过程中算法重利用不高的问题,我多次实验,并通过完善,通过分模块执行代码进行整合,最终解决了一些已知的问题。
数据结构图实验报告
数据结构教程上机实验报告实验七、图算法上机实现一、实验目的:1.了解熟知图的定义和图的基本术语,掌握图的几种存储结构。
2.掌握邻接矩阵和邻接表定义及特点,并通过实例解析掌握邻接矩阵和邻接表的类型定义。
3.掌握图的遍历的定义、复杂性分析及应用,并掌握图的遍历方法及其基本思想。
二、实验内容:1.建立无向图的邻接矩阵2.图的深度优先搜索3.图的广度优先搜索三、实验步骤及结果:1.建立无向图的邻接矩阵:1)源代码:#include "stdio.h"#include "stdlib.h"#define MAXSIZE 30typedef structchar vertex[MAXSIZE];//顶点为字符型且顶点表的长度小于MAXSIZEint edges[MAXSIZE][MAXSIZE];//边为整形且edges为邻近矩阵}MGraph;//MGraph为采用邻近矩阵存储的图类型void CreatMGraph(MGraph *g,int e,int n){//建立无向图的邻近矩阵g->egdes,n为顶点个数,e为边数int i,j,k;printf("Input data of vertexs(0~n-1):\n");for(i=0;i<n;i++)g->vertex[i]=i; //读入顶点信息for(i=0;i<n;i++)for(j=0;j<n;j++)g->edges[i][j]=0; //初始化邻接矩阵for(k=1;k<=e;k++)//输入e条边{printf("Input edges of(i,j):");scanf("%d,%d",&i,&j);g->edges[i][j]=1;g->edges[j][i]=1;}void main(){int i,j,n,e;MGraph *g; //建立指向采用邻接矩阵存储图类型指针g=(MGraph*)malloc(sizeof(MGraph));//生成采用邻接举证存储图类型的存储空间printf("Input size of MGraph:"); //输入邻接矩阵的大小scanf("%d",&n);printf("Input number of edge:"); //输入邻接矩阵的边数scanf("%d",&e);CreatMGraph(g,e,n); //生成存储图的邻接矩阵printf("Output MGraph:\n");//输出存储图的邻接矩阵for(i=0;i<n;i++){for(j=0;j<n;j++)printf("%4d",g->edges[i][j]);printf("\n");}}2)运行结果:2.图的深度优先搜索:1)源代码:#include "stdio.h"#include "stdlib.h"#define MAXSIZE 30typedef struct node//邻接表结点{int adjvex;//邻接点域struct node *next;//指向下一个邻接边结点的指针域}EdgeNode; //邻接表结点类型typedef struct vnode//顶点表结点{int vertex;//顶点域EdgeNode *firstedge; //指向邻接表第一个邻接边节点的指针域}VertexNode;//顶点表结点类型void CreatAdjlist(VertexNode g[],int e,int n){//建立无向图的邻接表,n为顶点数,e为边数,g[]存储n个顶点表结点EdgeNode *p;int i,j,k;printf("Input data of vetex(0~n-1);\n");for(i=0;i<n;i++)//建立有n个顶点的顶点表{g[i].vertex=i; //读入顶点i信息g[i].firstedge=NULL; //初始化指向顶点i的邻接表表头指针}for (k=1;k<=e;k++)//输入e条边{printf("Input edge of(i,j):");scanf("%d,%d",&i,&j);p=(EdgeNode*)malloc(sizeof(EdgeNode));p->adjvex=j; //在顶点vi的邻接表中添加邻接点为j的结点p->next=g[i].firstedge; //插入是在邻接表表头进行的g[i].firstedge=p;p=(EdgeNode*)malloc(sizeof(EdgeNode));p->adjvex=i; //在顶点vj的邻接表中添加邻接点为i的结点p->next=g[j].firstedge; //插入是在邻接表表头进行的g[j].firstedge=p;}}int visited[MAXSIZE]; //MAXSIZE为大于或等于无向图顶点个数的常量void DFS(VertexNode g[],int i){EdgeNode *p;printf("%4d",g[i].vertex); //输出顶点i信息,即访问顶点ivisited[i]=1;p=g[i].firstedge; //根据顶点i的指针firstedge查找其邻接表的第一个邻接边结点while(p!=NULL){if(!visited[p->adjvex]) //如果邻接的这个边结点未被访问过DFS(g,p->adjvex); //对这个边结点进行深度优先搜索p=p->next; //查找顶点i的下一个邻接边结点}}void DFSTraverse(VertexNode g[],int n){//深度优先搜索遍历以邻接表存储的图,其中g为顶点数,n为顶点个数int i;for(i=0;i<n;i++)visited[i]=0; //访问标志置0for(i=0;i<n;i++)//对n个顶点的图查找未访问过的顶点并由该顶点开始遍历if(!visited[i]) //当visited[i]等于0时即顶点i未访问过DFS(g,i); //从未访问过的顶点i开始遍历}void main(){int e,n;VertexNode g[MAXSIZE]; //定义顶点表结点类型数组gprintf("Input number of node:\n");//输入图中节点个数边的个数scanf("%d",&n);printf("Input number of edge:\n");//输入图中边的个数scanf("%d",&e);printf("Make adjlist:\n");CreatAdjlist(g,e,n); //建立无向图的邻接表printf("DFSTraverse:\n");DFSTraverse(g,n); //深度优先遍历以邻接表存储的无向图printf("\n");}2)运行结果:3.图的广度优先搜索:1)源代码:#include "stdio.h"#include "stdlib.h"#define MAXSIZE 30typedef struct node1//邻接表结点{int adjvex; //邻接点域struct node1 *next;//指向下一个邻接边结点的指针域}EdgeNode; //邻接表结点类型typedef struct vnode//顶点表结点{int vertex;//顶点域EdgeNode *firstedge; //指向邻接表第一个邻接边结点的指针域}VertexNode; //顶点表结点类型void CreatAdjlist(VertexNode g[],int e,int n){ //建立无向图的邻接表,n为顶点数,e为边数,g[]存储n个顶点表结点EdgeNode *p;int i,j,k;printf("Input data of vetex(0~n-1):\n");for(i=0;i<n;i++) //建立有n个顶点的顶点表{g[i].vertex=i; //读入顶点i信息g[i].firstedge=NULL; //初始化指向顶点i的邻接表表头指针}for(k=1;k<=e;k++) //输入e条边{printf("Input edge of(i,j):");scanf("%d,%d",&i,&j);p=(EdgeNode *)malloc(sizeof(EdgeNode));p->adjvex=j;//在定点vi的邻接表中添加邻接点为j的结点p->next=g[i].firstedge;//插入是在邻接表表头进行的g[i].firstedge=p;p=(EdgeNode *)malloc(sizeof(EdgeNode));p->adjvex=i; //在顶点vj的邻接表中添加邻接点为i的结点p->next=g[j].firstedge; //插入是在邻接表表头进行的g[j].firstedge=p;}}typedef struct node{int data;struct node *next;}QNode; //链队列结点的类型typedef struct{QNode *front,*rear; //将头、尾指针纳入到一个结构体的链队列}LQueue; //链队列类型void Init_LQueue(LQueue **q) //创建一个带头结点的空队列{QNode *p;*q=(LQueue *)malloc(sizeof(LQueue)); //申请带头、尾指针的链队列p=(QNode *)malloc(sizeof(QNode)); //申请链队列的头结点p->next=NULL;//头结点的next指针置为空(*q)->front=p; //队头指针指向头结点(*q)->rear=p; //队尾指针指向头结点}int Empty_LQueue(LQueue *q) //判队空{if(q->front==q->rear) //队为空return 1;elsereturn 0;}void In_LQueue(LQueue *q,int x) //入队{QNode *p;p=(QNode *)malloc(sizeof(QNode)); //申请新链队列结点p->data=x;p->next=NULL; //新结点作为队尾结点时其next 域为空q->rear->next=p; //将新结点*p链到原队尾结点之后q->rear=p; //使队尾指针指向新的队尾结点*p}void Out_LQueue(LQueue *q,int *x) //出队{QNode *p;if(Empty_LQueue(q))printf("Queue is empty!\n");//对空,出队失败else{p=q->front->next; //指针p指向链队列第一个数据结点(即对头结点)q->front->next=p->next;//头结点的next指针指向链队列第二个数据结点(即删除第一个数据结点)*x=p->data; //将删除的对头结点数据经由x返回free(p);if(q->front->next==NULL) //出队后队为空,则置为空队列q->rear=q->front;}}int visited[MAXSIZE]; //MAXSIZE为大于或等于无向图顶点个数的常量void BFS(VertexNode g[],LQueue *Q,int i){//广度优先搜索遍历邻接表存储的图,g为顶点表,Q为队指针,i为第i个顶点int j,*x=&j;EdgeNode *p;printf("%4d",g[i].vertex); //输出顶点i信息,即访问顶点ivisited[i]=1; //置顶点i为访问过标志In_LQueue(Q,i); //顶点i入队Qwhile(!Empty_LQueue(Q)) //当队Q非空时{Out_LQueue(Q,x); //对头顶点出队并送j(暂记为顶点j)p=g[j].firstedge;//根据顶点j的表头指针查找其邻接表的第一个邻接边结点while(p!=NULL){if(!visited[p->adjvex])//如果邻接的这个边结点未被访问过{printf("%4d",g[p->adjvex].vertex); //输出这个邻接边结点的顶点信息visited[p->adjvex]=1; //置该邻接边结点为访问过标志In_LQueue(Q,p->adjvex); //将该邻接边结点送人队Q}p=p->next;//在顶点j的邻接表中查找j的下一个邻接边结点}}}void main(){int e,n;VertexNode g[MAXSIZE];//定义顶点表结点类型数组g LQueue *q;printf("Input number of node:\n"); //输入图中结点个数scanf("%d",&n);printf("Input number of edge:\n");//输入图中边的个数scanf("%d",&e);printf("Make adjlist:\n ");CreatAdjlist(g,e,n);//建立无向图的邻接表Init_LQueue(&q);//队列q初始化printf("BFSTraverse:\n");BFS(g,q,0); //广度优先遍历以邻接表存储的无向图printf("\n");}2)运行结果:三、实验总结:1.通过本次试验让我对图的遍历以及图的深度和广度优先搜索有了更深刻的记忆和理解,将课本理论的知识得以实践。
数据结构图实验报告汇总
一、实验目的和要求(1)掌握图的相关概念,包括图,有向图,无向图,完全图,子图,连通图,度,入度,出度,简单回路和环等定义。
(2)重点掌握图的各种存储结构,包括邻接矩阵和邻接表等。
(3)重点掌握图的基本运算,包括创建图,输出图,深度优先遍历,广度优先遍历等。
(4)掌握图的其他运算 ,包括最小生成树,最短路径,拓扑排序和关键路径等算法。
(5)灵活运用图这种数据结构解决一些综合应用问题。
二、实验内容和方法(1)实验内容:1、编写一个程序algo8-1.cpp ,实现不带权图和带权图的邻接矩阵与邻接表的相互转换算法、输出邻接矩阵与邻接表的算法,并在此基础上设计一个程序exp8-1.cpp 实现如下功能:①建立如图1所示的有向图G 的邻接矩阵,并输出; ②由有向图G 的邻接矩阵产生邻接表,并输出; ③再由②的邻接表产生对应的邻接矩阵,并输出。
图12、编写一个程序algo8-2.cpp ,实现图的遍历运算,并在此基础上设计一个程序exp8-2.cpp 完成如下功能:①输出图1所示的有向图G 从顶点0开始的深度优先遍历序列(递归算法); ②输出图1所示的有向图G 从顶点0开始的深度优先遍历序列(非递归算法); ③输出图1所示的有向图G 从顶点0开始的广度优先遍历序列。
3、设计一个程序exp8-3.cpp,采用邻接表存储图,并输出图8.1(a )中从指定顶点1出发的所有深度优先遍历序列。
156 97584530 1 52 43(2)实验方法:1、综合运用课本所学的知识,用不同的算法实现在不同的程序功能。
2、结合指导老师的指导,解决程序中的问题,正确解决实际中存在的异常情况,逐步改善功能。
3、根据实验内容,编译程序。
三、实验环境:Windows 7,Visual C++6.0三、实验过程描述文件graph.h中定义了图的邻接矩阵表示类型和邻接表表示类型,该头文件在以下三个实验中都会使用到。
其代码如下:#ifndef GRAPH_H_INCLUDED#define GRAPH_H_INCLUDEDtypedef int InfoType;#define MAXV 100 //最大顶点个数#define INF 32767 //INF表示无限大//以下定义邻接矩阵类型typedef struct{int no;InfoType info;}VertexType;typedef struct{int edges[MAXV][MAXV];int n,e;VertexType vexs[MAXV];}MGraph;//以下定义邻接表类型typedef struct ANode{int adjvex;struct ANode* nextarc;InfoType info;}ArcNode;typedef int Vertex;typedef struct VNode{Vertex data;实验①源程序。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
图综合实验实验报告班级:计科12-1 学号:124010101 姓名:实验日期:2013.12.4一、实验目的1)熟悉图的基本操作。
2)掌握求图的最短路径算法。
3)加深对图的理解,逐步培养解决实际问题的编程能力。
二、实验环境装有Visual C++6.0的计算机。
本次实验共计4学时。
三、实验内容【基本要求】给定n个村庄之间的交通图。
若村庄i和j之间有路可通,则i和j用边连接,边上的权值Wij表示这条道路的长度。
现打算在这n个村庄中选定一个村庄建一所医院。
编写如下算法:(1)求出该医院应建在哪个村庄,才能使距离医院最远的村庄到医院的路程最短。
(2)求出该医院应建在哪个村庄,能使其它所有村庄到医院的路径总和最短。
【提示】✓对于问题(1),可以先求出每个村庄到其它所有村庄的最短路径,保存其最大值(表示假设医院建在该村庄,距离医院最远的村庄的路径长度);然后在这些最大值中找出一个最小值。
✓对于问题(2),可以先求出每个村庄到其它所有村庄的最短路径,保存其累加和(表示假设医院建在该村庄,其它所有村庄距离医院的路径总和);然后在这些和中找出一个最小值。
✓自己设定n个村庄的交通图。
例如下图所示:四、重要数据结构typedef struct /*图的定义*/{ int edges[MAXV][MAXV]; /*邻接矩阵*/int n,e; /*顶点数,弧数*/} MGraph; /*图的邻接矩阵类型*/五、实现思路分析void Dijkstra(MGraph g,int v); //狄克斯特拉算法void Dispath(int dist[],int path[],int s[],int n,int v);void Ppath(int path[],int i,int v);void He(MGraph g,int v);//情况一void Slove(MGraph g,int v);//情况二六、程序调试问题分析狄克斯特拉算法输出的dist【i】总为0,在主函数对g.edges[i][j]先赋值即可。
七、实验总结通过这次实验,我对最小生成树有了更好的认识。
在实验过程中,我掌握了最短路径的构造方法,学会了如何将理论知识转换为实际应用。
同时,在解决程序中遇到的一些问题的同时,我也对调试技巧有了更好的掌握,分析问题的能力也略有提高。
在实验中,我遇到了许多难点,这就需要我们有扎实的基础,需要有灵活的头脑,只有不断的练习,不断的训练,我们才能处理各种问题。
在以后的学习中,我要不断的努力,多联系,多思考,我相信我能有所进步的。
#include<stdio.h>#include<malloc.h>#include<string.h>#include<iostream>using namespace std;#define MAXV 100 /*最大顶点个数*/#define INF 32767 /*INF表示∞*/int s[MAXV];int dist[MAXV];int path[MAXV];//int dist[MAXV];//typedef int InfoType;//typedef struct//{ int no; /*顶点编号*/// InfoType info; /*顶点其他信息*///} VertexType; /*顶点类型*/typedef struct/*图的定义*/{ int edges[MAXV][MAXV]; /*邻接矩阵*/ int n,e; /*顶点数,弧数*/} MGraph; /*图的邻接矩阵类型*/typedef struct{int u; //边的起始顶点int v; //边的终止顶点int w; //边的权值} Edge;void Dijkstra(MGraph g,int v); //狄克斯特拉算法void Dispath(int dist[],int path[],int s[],int n,int v); void Ppath(int path[],int i,int v);void He(MGraph g,int v);//情况一void Slove(MGraph g,int v);int main(){MGraph g;int i,u,v,w,j,n;freopen("d:in.txt","r",stdin);g.n = 6;g.e = 10;for( i=0;i<g.n;i++)for( j=0;j<g.n;j++){if(i!=j)g.edges[i][j]=INF;else g.edges[i][j]=0;}for (i = 0; i < g.e; i++){scanf("%d %d %d",&u,&v,&w);g.edges[u][v] = w;g.edges[v][u] = w;}for(i = 0; i < g.n; i++)Dijkstra(g,i);printf("\n\n");He(g,0);printf("\n\n");// for(i = 0; i < g.n; i++)Slove(g,i);return 0;}void Ppath(int path[],int i,int v){int k;k = path[i];if(k == v)return;Ppath(path,k,v);printf("%d,",k);}void Dispath(int dist[],int path[],int s[],int n,int v){int i;for(i = 0; i < n; i++)if(s[i] == 1 && i != v){printf("从%d到%d的最短路径长度为:%d\t路径为:",v,i,dist[i]);printf("%d,",v);Ppath(path,i,v);printf("%d\n",i);}}void Dijkstra(MGraph g,int v) //狄克斯特拉算法{int dist[MAXV],path[MAXV];int s[MAXV];int mindis,i,j,u;for(i = 0; i < g.n; i ++){dist[i] = g.edges[v][i];s[i] = 0;if(g.edges[v][i]<INF)path[i] = v;elsepath[i] = -1;}s[v] = 1;path[v] = 0;for(i = 0; i <g.n; i++){mindis = INF;for(j = 0;j <g.n; j++)if(s[j] == 0 && dist[j] < mindis){u = j;mindis = dist[j];}s[u] = 1;for(j = 0; j < g.n; j++)if(s[j] == 0)if(g.edges[u][j] < INF && dist[u] + g.edges[u][j] < dist[j]){dist[j] = dist[u] + g.edges[u][j];path[j] = u;}}Dispath(dist,path,s,g.n,v);}void He(MGraph g,int v){int i,j,max,min,k = -1;max = -INF;min = INF;for(i = 0; i < g.n; i++){for(j = 0; j < g.n; j++){if(g.edges[i][j] > max && i != j && g.edges[i][j] != INF)max = g.edges[i][j];}if(max < min){min = max;k = i;}printf("%d出发最远距离:%d\n",i,max);}printf("\n");printf("医院建在%d能使距离医院最远的村庄到医院的路程最短,最短路程为%d\n",k,min);}void Slove(MGraph g,int v){int min=INF,max=-INF;int sum;int k=-1;for(int i=0;i<g.n;i++){sum=0;for(int j=0;j<g.n;j++){// if(g.edges[v][j] != INF)// {// sum = sum + dist[j];// }// elsesum = sum + g.edges[v][j];}if(min>sum){min=sum;k=i;}cout<<i<<"到所有点之和: "<<sum<<endl;}// cout<<endl<<"总和最短城市为: "<<k<<"距离 : "<<min<<endl; }/* 输入数据0 1 51 2 42 3 53 4 54 5 15 0 30 2 83 5 60 3 75 2 9 */。