数据结构课程设计报告.doc
《数据结构课程设计报告.doc》由会员分享,可在线阅读,更多相关《数据结构课程设计报告.doc(22页珍藏版)》请在沃文网上搜索。
1、题目:在n个城市之间建设网络,只需保证连通即可,求最经济的架设方法。存储结构采用(邻接表和邻接矩阵)两种,采用课本上的两种求解算法。一、需求分析1.1已知一个无向连通网表示n个城市以及城市间可能设置的通信网络线路,其中网的顶点表示城市,边表示两个城市之间的线路,赋于边上的权值表示相应的代价。对于n个点的连通网能建立许多不同的生成树,每一棵生成树都可以是一个通信网。我们要选择一棵生成树,使总的耗费最小。1.2该无向连通图的建立需要使用两种存储结构,即邻接表和邻接矩阵。1.3实现最小生成树需要使用两种算法。即普里姆算法和克鲁斯卡尔。1.4程序通过人机交互实现数据的输入和输出。1.5测试数据 (a,
2、b):2 ; (a,c):3; (a,d):4; (c,d):4; (b,d):5二、概要设计程序分为两大部分存储部分和算法部分;存储部分分为邻接矩阵和邻接表,而且包含了两者直接的互相转换;算法部分分为普里母算法和克鲁斯卡尔算法。1.抽象数据类型图的定义如下ADT Graph数据对象V;V是具有相同特性的数据元素的集合,成为顶点集。数据关系R: R = VRVR = (v,w)|v,w为V集合中的元素,(v,w)表示v和w之间存在的路径基本操作P;CreateMGraph(MGraph *G)初始条件:V是图的顶点集,VR是图的边的集合。操作结果:按V和VR的定义构造图G,用邻接矩阵存储。Cr
3、eateALGraph(ALGraph *G)初始条件:V是图的顶点集,VR是图的边的集合。操作结果:按V和VR的定义构造图G,用邻接表存储。LocateVex(G,u)初始条件:图G存在,u和G中顶点有相同的特征。操作结果:若G中存在顶点u,则返回该顶点在图中的位置;否则返回其他信息。MiniSpanTree_PRIM(G, u)初始条件:图G存在,u是图G中的一个顶点。操作结果:用普利姆算法从第u个顶点出发构造网G的最小生成树T,输出T的各条边。Kriuskal(G)初始条件:图G存在操作结果:用克鲁斯卡尔算法构造图G的最小生成树T,输出T的各条边。ListToMat(MGraph *G1
4、,ALGraph *G2)初始条件:图G2存在操作结果:把图的邻接表存储结构转换为邻接矩阵存储结构,用图G1表示。MatToList(MGraph *G1,ALGraph *G2)初始条件:图G1存在操作结果:把图的邻接矩阵存储结构转换为邻接表存储结构,用图G2表示。LocateVex(MGraph *G,VertexType u)初始条件:图G存在,u和G中顶点有相同特征操作结果:若G中存在顶点u,则返回该顶点在图中位置;否则返回-1ADT Graph2.主程序 void main()创建图G,并按不同的存储结构输出。对图的存储结构进行转换使用算法构造最小生成树并输出各边3.模块间的调用关系
5、主模块子模块 三、详细设计1.图和顶点的定义#define OK 1#define ERROR 0#define TURE 1#define FALSE 0#define OVERFLOW -1#define INFEASIBLE -2typedef int Status;#define INFINITY 32767 /两地之间没有架设线路的权值为最大数。#define MAX_VERTEX_NUM 20 /城市的数目最大为20#define MAX_NAME 5/城市名称的最大长度为5typedef char VertexTypeMAX_NAME;/城市的名称用字符数组存储typedef i
6、nt VRType; /两城市间的关系类型1.1邻接矩阵存储表示的图的结构体类型的定义typedef struct ArcCell VRType adj; /*顶点关系类型。对无权图,用1(是)或0(否)表示相邻否*/ /*对带权全图,则为权值类型*/ ArcCell,AdjMatrixMAX_VERTEX_NUMMAX_VERTEX_NUM;typedef struct VertexType vexsMAX_VERTEX_NUM; /*顶点向量*/ AdjMatrix arcs; /*邻接矩阵*/ int vexnum,arcnum; /*图的当前顶点数和弧数*/ MGraph; 1.2邻接
7、表类型存储表示的图的结构体类型的定义 typedef struct ANode /* 弧的结点结构类型 */ int end; /弧尾在邻接表头结点中的位置 int begin; /弧头在邻接表头结点中的位置 int weight; /* 该弧的相关信息,这里用于存放权值 */ struct ANode *nextarc; /* 指向下一条弧的指针 */ ANode;typedef struct Vnode /* 邻接表头结点的类型 */ VertexType vertex; /* 顶点信息,城市名称 */ int bianhao; /城市在邻接表头结点数组中的相应编号 ANode *firs
8、tarc; /* 指向第一条弧 */ VNode,AdjListMAX_VERTEX_NUM; /* AdjList是邻接表类型 */typedef struct AdjList adjlist; /* 邻接表 */ int vexnum,arcnum; /* 图中顶点数n和边数e */ ALGraph; 2.Prim算法的思想假设V是图中顶点的集合,E是图中边的集合,TE为最小生成树中的边的集合,则prim算法通过以下步骤可以得到最小生成树: (1)初始化:U=u 0,TE=f。此步骤设立一个只有结点u 0的结点集U和一个空的边集TE作为最小生成树的初始形态,在随后的算法执行中,这个形态会不
9、断的发生变化,直到得到最小生成树为止。 (2)在所有uU,vVU的边(u,v)E中,找一条权最小的边(u 0,v 0),将此边加进集合TE中,并将此边的非U中顶点加入U中。此步骤的功能是在边集E中找一条边,要求这条边满足以下条件:首先边的两个顶点要分别在顶点集合U和VU中,其次边的权要最小。找到这条边以后,把这条边放到边集TE中,并把这条边上不在U中的那个顶点加入到U中。这一步骤在算法中应执行多次,每执行一次,集合TE和U都将发生变化,分别增加一条边和一个顶点,因此,TE和U是两个动态的集合,这一点在理解算法时要密切注意。 (3)如果U=V,则算法结束;否则重复步骤2。可以把本步骤看成循环终止
10、条件。我们可以算出当U=V时,步骤2共执行了n1次(设n为图中顶点的数目),TE中也增加了n1条边,这n1条边就是需要求出的最小生成树的边。Prim算法假设网中有N个顶点,则第一个进行初始化的循环语句频度为n,第二个循环语句的频度为n-1。其中有两个内循环;由此普里母算法的时间复杂度为O(n2),与网中的边数无关!3.克鲁斯卡尔算法的思想为假设 WN=(V,E) 是一个含有 n 个顶点的连通网,则按照克鲁斯卡尔算法构造最小生成树的过程为:(1)先构造一个只含 n 个顶点,而边集为空的子图,若将该子图中各个顶点看成是各棵树上的根结点,则它是一个含有 n 棵树的一个森林。(2)从网的边集 E 中选
11、取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,也就是说,将这两个顶点分别所在的两棵树合成一棵树;反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之。(3)依次类推,重复上述操作,直至森林中只有一棵树,也即子图中含有 n-1条边为止。克鲁斯卡尔算法至多对e条边各扫描一次时间复杂度为O(eloge)。4.编写程序使用到的函数为 (a)程序中用来实现邻接矩阵和邻接表存储、输出以及互相转化的函数Status InitALGraph(ALGraph *G)/初始化邻接表void CreateALGraph(ALGraph *G)/创建邻接表Stat
12、us InitMGraph(MGraph *G)/初始化邻接表Status CreateMGraph(MGraph *G)/创建邻接表Status MatToList(MGraph *G1,ALGraph *G2)/将邻接矩阵G1转换成邻接表G2Status ListToMat(MGraph *G1,ALGraph *G2)/将邻接表G1转换成邻接矩阵G2Status PrintMGraph(MGraph *G)/输出邻接矩阵gStatus PrintALGraph(ALGraph *G)/输出邻接表G(b)程序中用来完成prim和kriuskal算法的函数int mininum(minsid
13、e closedge,MGraph *G)/ 求closedege数组中lowcost的最小正值void MiniSpanTree_PRIM(MGraph *G,VertexType u)/ 用普利姆算法从第u个顶点出发构造网G的最小生成树T,输出T的各条边void InsertSort(EdgeType E,int n)/对E0.n-1按权值递增有序的进行直接插入排序void Kriuskal(ALGraph *G)/克鲁斯卡尔算法(c) 查找顶点U在图中的位置int LocateVex(MGraph *G,VertexType u)/查找顶点U在图中的位置5.主函数模块为:void mai
14、n()定义邻接矩阵存储结构的图;定义邻接表存储结构的图;选择一种存储结构画出图,并输出;邻接矩阵和邻接表相互转化,得到两种类型的存储图,并输出转换后的图;选择一种算法得到最小生成树并输出生成树的各边。6.模块间的调用层次main()void CreateALGraph(ALGraph *G)Status CreateMGraph(MGraph *G)Status MatToList(MGraph *G1,ALGraph *G2)Status ListToMat(MGraph *G1,ALGraph *G2)void MiniSpanTree_PRIM(MGraph *G,VertexType
15、u)void Kriuskal(ALGraph *G)Status InitALGraph(ALGraph *G)Status InitMGraph(MGraph *G)Status PrintMGraph(MGraph *G)Status PrintALGraph(ALGraph *G)int mininum(minside closedge,MGraph *G)void InsertSort(EdgeType E,int n)int LocateVex(MGraph *G,VertexType u) 四、编码与测试这个阶段主要是对代码的编写及代码正确性的检验。通过前面的详细设计的分析,这个
16、阶段是完成各个函数的功能,在编程的过程中出现了许多的错误,导致功能的无法实现,出现的错误主要有及心的:1.对于结构体的成员的调用 心得:结构体变量名调用函数时使用符号.,对于结构体指针使用符号-或者是先使用*取得变量名在使用.调用成员。2.函数调用时指针的传递 心得:这个主要是C+与C语言的区别,在C+中函数的参数中有&,表示该变量为返回值数据,而在C语言中,据我所学确没有这样的用法。3.非法字符的使用 心的:非法字符的使用往往让人很难找到错误,而且Win-TC环境给出的提示往往是错误的。产生这种错误的原因是汉语的标识符的出现,往后要注意了。4.字符串的输入及输出心的:对于字符串的输入输出都应
17、使用取地址符号。5数据的输入心的:数据的输入可以使用空格符或取地址符号,但是空格符的输入常常容易发生错误,最好使用换行符。6.程序的输出出现错误的数据心的:程序总是会莫名奇妙的输出错误的信息,有时候输出是错误的,有时候是正确的,很奇怪,建议以后出现这类型情况时先看代码,若没有错误,那就等会再运行一边。7.命令行的消失心的:有时候在输入数据的过程中,命令行就会突然消失,在同学的建议下加了getchar();语句就不出现这类情况了,不明白是为什么。8.命令行重复输出相同的数据心的:这种情况很有可能是出现了死循环,这不仅发生在循环语句的情况下,对于结点指针的指向也会导致是循环。五、综合测试综合测试其
18、实是对程序的总体测试,但在编码阶段已经对语句的进行了测试,在总体测试阶段多采用几组数据,在编码阶段的数据可以简单一些,但在综合测试阶段要用使用比较复杂的数据,可以检测到在编码阶段不宜发现的错误。在综合测试阶段发现的错误:对于邻接表的指针的取向。测试数据:(a,b):2 ; (a,c):3; (a,d):4; (c,d):4; (b,d):5采用邻接表存储的输入及邻接表转换为邻接矩阵并显示通过Prim算法显示最小生成树的各边采用邻接矩阵存储的输入邻接矩阵转换为邻接表并显示及通过Prim算法显示最小生成树的各边通过Kruskal算法显示最小生成数的各边六、课程总结认识: 对于编程,假期一个月的学习
- 1.请仔细阅读文档,确保文档完整性,对于不预览、不比对内容而直接下载带来的问题本站不予受理。
- 2.下载的文档,不会出现我们的网址水印。
- 3、该文档所得收入(下载+内容+预览)归上传者、原创作者;如果您是本文档原作者,请点此认领!既往收益都归您。
下载文档到电脑,查找使用更方便
20 积分
下载 | 加入VIP,下载更划算! |
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 报告
