1、2号C+ 课程设计报告课 题: 构造可以使n个城市连接的最小生成树 专业班级: 学 号: 姓 名: 指导教师: 评阅意见:评定成绩: 指导老师签名: 年 月 日目 录1 课程设计的目的和意义 32 需求分析 43 系统(项目)设计 5一、设计思路及方案 5二、模块的设计及介绍 54 系统实现 105 系统调试 14参考文献 18附录 源程序 191 课程设计的目的和意义据数据结构课堂讲授及书本内容,学生做相应的自主练习,消化课堂所讲解的内容;通过调试典型例题或习题积累调试C及C+程序的经验;通过完成课程设计中的编程题,逐渐培养学生的编程能力、用计算机解决实际问题的能力。“数据结构”作为计算机专
2、业基础课,该课程的目标就是使学生学会如何从问题出发,分析数据,构造求解问题的数据结构和算法,培养学生有一定进行较复杂程序设计的能力。本次课程设计的内容是用最小生成树的构造来表示城市间的最小代价即最小距离,最小生成树可以用连接矩阵和连接表表示,而它们的区别就是连接矩阵一般用来表示密集型的网络,连接表一般用来表示稀疏型的网络,连接矩阵是用数组来存储,连接了是用链表来存储的,比较复杂密集型的网络就网连接矩阵较适用了,设计中运用了Prim算法,“构造可以使n个城市连接的最小生成树”问题就是用连接矩阵和Prim算法处理的一个实际应用。通过这个题目的设计实例,了解了最小生成树的实际运用意义,也了解连接矩阵
3、和连接表的相同与不同之处,进一步加深了对最小生成树结构和Prim算法的理解。通过这次课程设计,一方面使学生加深对课内所学的有关数据的逻辑结构和存储表示、数据结构的选择和应用、算法的设计和时空分析等课程基本内容的理解,另一方面,使学生在程序设计方法(如抽象数据类型、结构化分析、模块化设计和结构化设计)、C和C+语言编程环境以及程序的调试和测试方面受到比较系统的严格的训练。 2 需求分析题目:构造可以使n个城市连接的最小生成树问题描述:给定一个地区的n个城市间的距离网,用Prim算法或Kruskal算法建立最小生成树,并计算得到的最小生成树的代价。基本要求:1、城市间的距离网采用邻接矩阵表示,邻接
4、矩阵的存储结构定义采用课本中给出的定义,若两个城市之间不存在道路,则将相应边的权值设为自己定义的无穷大值。要求在屏幕上显示得到的最小生成树中包括了哪些城市间的道路,并显示得到的最小生成树的代价。2、表示城市间距离网的邻接矩阵(要求至少6个城市,10条边)3、最小生成树中包括的边及其权值,并显示得到的最小生成树的代价。3 系统(项目)设计(包括总体设计和详细设计)一. 设计思想及方案:n个顶点(城市)的连通图应该至少有n-1条边,而生成树正好有n-1条边,所以生成树是对应的连通图的极小连通子图。带权的无向图,经过遍历得到的生成树也是带权的,最小生成树即权值最小的生成树。所以要求图的最小生成树,即
5、只要求权值最小的极小连通子图。这实际上是求图的一个生成树。同时还要考虑造价最低这个条件。一棵树的权定义为它所含各边的权之和。一个连通网络的最小生成树是该图所有生成树中权最小的生成树普里姆算法(Prim)算法:设N=(V,E)是连通图,TE是N上最小生成树中边的集合,U为V中具有最小生成树的顶点集合,初始时,TN为空,U=uo( uoV),重复下叙操作:在所有uU、vV-U的边(u,v)E中找一条代价最小的边(u0 ,v0 )并入集合TE,同时v0 并入集合TE,同时, 直到U=V为止,此时TE必有n-1条边,且T=(V,TE)为N的最小生成树。二模块的设计及介绍(1). 主程序模块 void
6、main()接受命令;处理命令;Coutendl”命令”=”是否继续?y/n”; (2). 创建链接矩阵模块 int creatMGraph_L(参数) for 接受命令;处理命令; cout命令endl; (3). 最小生成树Prim算法及代价模块int prim(参数) for 接受命令; 处理命令 cout命令endl;三城市分布及各城市距离图 (0:城市a;1:城市b;2:城市c;3:城市d;4:城市e;5:城市f) 城市分布无向图(C) 四主要模块程序流程图(1)主函数程序流程图(2).创建连接矩阵流程图(3). 最小生成树Prim算法程序流程图 4 系统实现各模块关键代码及算法的解
7、释:(1).主函数模块代码 algraph gra; MGraph_L G; int i,d,g2020; char a=a; d=creatMGraph_L(G); vnode v; coutendl注意:若该图为非强连通图(含有多个连通分量)时endl 最小生成树不存在,则显示为非法值endlendl; cout菜单endlendl; cout0、显示该图的邻接矩阵endl; cout1、最小生成树PRIM算法及代价endl; int s; char y=y; while(y=y) cout请选择菜单:s; switch(s) case 0: cout邻接矩阵显示如下:endl; ljjz
8、print(G); break; case 1: for(i=0;i!=G.vexnum;+i) for(int j=0;j!=G.vexnum;+j) gi+1j+1=G.arcsij.adj; coutprim:endl; prim(g,d); break; coutendly; if(y=n) break; 程序解释:该主函数用一个循环语句,来执行其它的函数的功能。从键盘输入顶点数和边数上限,再调用定义连接矩阵的函数,后输出创建连接矩阵的信息,再调用creatMGraph()函数,接着进入菜单,然后再选择输入一个数确定是要输出连接矩阵还是最小生成树及代价,最后选择输入确定字母y或N确定是
9、否继续。(2). 邻接矩阵定义模块代码typedef struct ArcCell int adj; char *info;ArcCell,AdjMatrix2020;typedef struct char vexs20; AdjMatrix arcs; int vexnum,arcnum;MGraph_L;int localvex(MGraph_L G,char v) int i=0; while(G.vexsi!=v) +i; return i;程序解释:用typedef struct定义连接矩阵,通过二维数组来存储连接矩阵,并设定参数的最大值为20。(3). 创建链接矩阵模块代码int
10、creatMGraph_L(MGraph_L &G) char v1,v2; int i,j,w; cout创建无向图(城市分布图)endl请输入图G顶点(城市)和弧(边)的个数:(4 6)不包括“()”G.vexnumG.arcnum; for(i=0;i!=G.vexnum;+i) cout输入顶点(城市)iG.vexsi; for(i=0;i!=G.vexnum;+i)for(j=0;j!=G.vexnum;+j) G.arcsij.adj=int_max; G.arcsij.info=NULL; for(int k=0;k!=G.arcnum;+k) cout输入一条边依附的顶点(城市
11、)和权(距离):(a b 3)不包括“()”v1v2w; i=localvex(G,v1); j=localvex(G,v2); G.arcsij.adj=w; G.arcsji.adj=w; cout图G邻接矩阵创建成功!endl; return G.vexnum;程序解释:该语句是从键盘输入顶点数和边数,输入顶点和权值,通过循环语句的调用,最后调用creatMGraph_L()创建连接矩阵 (4). 最小生成树Prim算法及代价模块代码int prim(int gmax,int n) int lowcostmax,prevexmax; int i,j,k,min; int sum=o; f
12、or(i=2;i=n;i+) lowcosti=g1i; /初始化 prevexi=1; lowcost1=0; for(i=2;i=n;i+) /形成n-1条边的生成树 min=inf; k=0; for(j=2;j=n;j+) if(lowcostjmin)&(lowcostj!=0) min=lowcostj; k=j; printf(%d,%d)%dt,prevexk-1,k-1,min); sum+=min; lowcostk=0; for(j=2;j=n;j+) if(gkjlowcostj) lowcostj=gkj; prevexj=k; printf(n); cout最少生成
13、树的代价:;coutsum;return 0; 程序解释:该语句运用一系列的循环语句来实现的,利用前面的创建好的链接矩阵,通过各边权值的比较,最后调用prim()函数,实现最小生成树的生成,同时运用sum把最小生成树各边权值相加得到最小生成树的代价。5 系统调试1、运行程序后,初界面:2、输入顶点和弧的个数后的界面:. 3、输入顶点后的界面:4、输入一条边依附的顶点和权值后的界面:5、输入确定数字0及确定字母y后的界面:6、输入确定数字1及确定字母n后的界面:小结回顾起此次课程设计,至今我仍感慨颇多,从理论到实践,在整整一周的日子里,我学到很多很多的东西,不仅巩固了以前所学过的知识,而且学到了
14、很多在书本上所没有学到过的内容。培养了独立思考,深入研究,分析问题、解决问题的能力,提高综合运用本课程所学知识的能力,还对课程设计的基的设计方法、步骤、思路、有了深刻的了解与认识,并对存储结构和函数的调用,比如连接矩阵、链接表、树、图等存储结构,for引导的循环语句,特别是Prim算法理解的更深。我本次课程设计的题目是构造可以使n个城市连接的最小生成树,开始看到题目觉得自己题目对自己比较有利,因为自己对最小生成树这节的内容比较熟悉 ,但是刚一开始编程觉得自己无从下手,这就看出自己的问题了,在书本上学的只是一些很肤浅的东西,在实际运用中显得很无力,但是通过自己慢慢查阅相关书籍和相关网站后,编程的
15、进度慢慢加快了,一些相关的难点逐步得到解决,最终还是完成了此次课程设计中最主要的几个步骤。通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才是真正的知识,才能提高自己的实际动手能力和独立思考的能力。在设计的过程遇到了各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,通过这次课程设计,把以前所学过的知识重新温故,巩固了所学的知识。参考文献 1 数据结构(C语言版),北京:清华大学出版社,20022 数据结构课程设计,北京:机械工业出版社,20043 C语
16、言程序设计教程,上海:高等教育出版社,20064 朱建明,马建峰.基于容忍入侵的数据库体系结构J.西安电子科技大学学报,20035各个与数据结构相关的网站附录 源程序#include #include using namespace std; #define int_max 10000#define inf 9999 #define max 20/邻接矩阵定义typedef struct ArcCell int adj; char *info;ArcCell,AdjMatrix2020;typedef struct char vexs20; AdjMatrix arcs; int vexnum
17、,arcnum;MGraph_L;/int localvex(MGraph_L G,char v)/返回V的位置 int i=0; while(G.vexsi!=v) +i; return i;int creatMGraph_L(MGraph_L &G)/创建图用邻接矩阵表示 char v1,v2; int i,j,w; cout创建无向图(城市分布图)endl请输入图G顶点(城市)和弧(边)的个数:(4 6)不包括“()”G.vexnumG.arcnum; for(i=0;i!=G.vexnum;+i) cout输入顶点(城市)iG.vexsi; for(i=0;i!=G.vexnum;+i
18、) for(j=0;j!=G.vexnum;+j) G.arcsij.adj=int_max; G.arcsij.info=NULL; for(int k=0;k!=G.arcnum;+k) cout输入一条边依附的顶点(城市)和权(距离):(a b 3)不包括“()”v1v2w;/输入一条边依附的两点及权值 i=localvex(G,v1);/确定顶点V1和V2在图中的位置 j=localvex(G,v2); G.arcsij.adj=w; G.arcsji.adj=w; cout图G邻接矩阵创建成功!endl; return G.vexnum;void ljjzprint(MGraph_L
19、 G) int i,j; for(i=0;i!=G.vexnum;+i) for(j=0;j!=G.vexnum;+j) coutG.arcsij.adj ; coutendl; int visitedmax;/访问标记int we;typedef struct arcnode/弧结点 int adjvex;/该弧指向的顶点的位置 struct arcnode *nextarc;/弧尾相同的下一条弧 char *info;/该弧信息arcnode;typedef struct vnode/邻接链表顶点头接点 char data;/结点信息 arcnode *firstarc;/指向第一条依附该
20、结点的弧的指针vnode,adjlist;typedef struct/图的定义 adjlist verticesmax; int vexnum,arcnum; int kind;algraph;int prim(int gmax,int n) /最小生成树PRIM算法 int lowcostmax,prevexmax; /LOWCOST存储当前集合U分别到剩余结点的最短路径 /prevex存储最短路径在U中的结点 int i,j,k,min; int sum=o; for(i=2;i=n;i+) /n个顶点,n-1条边 lowcosti=g1i; /初始化 prevexi=1; /顶点未加入
21、到最小生成树中 lowcost1=0; /标志顶点1加入U集合 for(i=2;i=n;i+) /形成n-1条边的生成树 min=inf; k=0; for(j=2;j=n;j+) /寻找满足边的一个顶点在U,另一个顶点在V的最小边 if(lowcostjmin)&(lowcostj!=0) min=lowcostj; k=j; printf(%d,%d)%dt,prevexk-1,k-1,min); sum+=min; lowcostk=0; /顶点k加入U for(j=2;j=n;j+) /修改由顶点k到其他顶点边的权值 if(gkjlowcostj) lowcostj=gkj; prev
22、exj=k; printf(n); cout最少生成树的代价:;coutsum;return 0; void main() algraph gra; MGraph_L G; int i,d,g2020; char a=a; d=creatMGraph_L(G); vnode v; coutendl注意:若该图为非强连通图(含有多个连通分量)时endl 最小生成树不存在,则显示为非法值endlendl; cout菜单endlendl; cout0、显示该图的邻接矩阵endl; cout1、最小生成树PRIM算法endl; int s; char y=y; while(y=y) cout请选择菜单:s; switch(s) case 0: cout邻接矩阵显示如下:endl; ljjzprint(G); break; case 1: for(i=0;i!=G.vexnum;+i) for(int j=0;j!=G.vexnum;+j) gi+1j+1=G.arcsij.adj; coutprim:endl; prim(g,d); break; coutendly; if(y=n) break;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1