大数据结构最小生成树解决实际问题地课程设计.docx
- 文档编号:30040261
- 上传时间:2023-08-04
- 格式:DOCX
- 页数:26
- 大小:153.23KB
大数据结构最小生成树解决实际问题地课程设计.docx
《大数据结构最小生成树解决实际问题地课程设计.docx》由会员分享,可在线阅读,更多相关《大数据结构最小生成树解决实际问题地课程设计.docx(26页珍藏版)》请在冰豆网上搜索。
大数据结构最小生成树解决实际问题地课程设计
工业应用技术学院
课程设计说明书
题目:
关于最小生成树解决实际问题
姓名:
周红言
院〔系〕:
信息工程学院
专业班级:
16级计算机科学与技术1班
学号:
1601110026
指导教师:
秀丽
成绩:
时间:
2017年12月11日至2017年1月7日
工业应用技术学院
课程设计任务书
题目关于最小生成树解决实际问题
专业、班级16级计算机科学与技术1班学号1601110026
__周红言
主要容:
1、熟悉系统实现工具和上机环境。
2、本课题的可行性分析、开发计划,通过调研完成系统的需求分析。
简要表示技术可行性、经济可行性和操作可行性等。
3.根据需求分析进展总体设计、数据库设计以与系统的设计与实现等。
根本要求:
1.要用到图的先相关数据结构和求最小生成树的两种数据结构算法普里姆算法和克鲁斯卡尔算法,以与储存图的边和点的邻接矩阵。
2.学会使用MicrosoftVisualC++6.0集成开发环境。
主要参考资料:
[1]严蔚敏.数据结构〔C语言版〕[M].:
清华大学,1997.
[2]谭浩强.C程序设计〔第三版〕[M].:
清华大学,2005.1.
[3]二霍红卫算法设计与分析〔」电子科技大学,2005.113-127.
完成期限:
20178
指导教师签名:
课程负责人签名:
摘要
最小生成树是数据结构中图的一种重要应用,在图中对于n个顶点的连通网可以建立许多不同的生成树,最小生成树就是在所有生成树中总的代价最小的生成树。
本课程设计是以邻接矩阵作为图的存储结构,分别采用Prim和Kruskal算法求最小生成树。
Kruskal算法和Prim算法是求最小生成树的常用算法它们分别适用于稠密图和稀疏图。
最小生成树的应用非常的广,如矿井通风设计和改造最优化方面以与如何搭建最短的网络线缆,构建造价最低的通讯网络
关键词:
kruskal算法;prim算法;数据结构;最小生成树
第一章概述
1.1课程设计目的
本课程设计的目的是了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等根本方法和技能;提高综合运用所学的理论知识和方法独立分析和解决问题的能力;训练用系统的观点和软件开发一般规进展软件开发。
1.2课程设计任务
问题描述:
一个无向连通网表示n个城市以与城市间可能设置的通信线路,其中网的顶点表示城市,边表示两个城市之间的线路,赋于边上的权值表示相应的代价。
对于n个点的连通网能建立许多不同的生成树,每一棵生成树都可以是一个通信网。
我们要选择一棵生成树,使总的消耗最小。
在n个城市之间建设网络,只需保证连同即可,求最经济的架设方法。
存储结构采用多种。
求解算法多种。
程序可利用克鲁斯卡尔算法或prim算法生成最小生成树。
1.3模块分析
主模块:
用于生成界面和调用各个子模块。
Kruscal模块:
以kruscal算法实现最小生成树。
Prim模块:
以prim算法实现最小生成树。
邻接表模块:
用邻接表方式存储图。
邻接表输出模块:
输出邻接表。
邻接表矩阵模块:
用邻接矩阵方式存储图。
第二章概要设计说明
1)建立一个图,其存储方式可以采用邻接矩阵形式,需要定义两个数组,一个存储顶点,一个存储边,存储边的数组明确节点间的连通关系和边的权值;。
2)利用普里姆算法和克鲁斯卡尔算法求网的最小生成树
3)按顺序输出生成树中各条边以与它们的权值。
构造最小生成树的方法:
最初生成树为空,即没有一个结点和一条边,首先选择一个顶点作为生成树的根,然后每次从不在生成树中的边中选择一条权值尽可能小的边,为了保证参加到生成树中的边不会造成回路,与该边邻接的两个顶点必须一个已经在生成树中,一个如此不在生成树中,假如网中有n个顶点〔这里考虑的网是一个连通无向图〕,如此按这种条件选择n-1边就可以得到这个网的最小生成树了。
详细的过程可以描述为:
设置2个集合,U集合中的元素是在生成树中的结点,V-U集合中的元素是不在生成树中的顶点。
首先选择一个作为生成树根结点的顶点,并将它放入U集合,然后在那些一端顶点在U集合中,而另一端顶点在V-U集合中的边中找一条权最小的边,并把这条边和那个不在U集合中的顶点参加到生成树中,即输出这条边,然后将其顶点添加到U集合中,重复这个操作n-1次。
2.3设计思路
问题的解决分别采用普利姆算法以与克鲁斯卡尔算法。
1〕普利姆算法就是先选择根,把它放到一个集合u中,剩余的顶点放在集合v中。
然后选择顶点与v中顶点之间权值最小的一条边,以此类推,如果达到最后一个如此返回上一个顶点。
2〕克鲁斯卡尔算法就是写出所有的顶点,选择权最小的边,然后写出第二小的,以此类推,最终要有一个判断是否生成环,不生成如此得到克鲁斯卡尔的最小生成树。
2.5.1抽象数据类型
ADTGraph
{数据对象V:
v是具有一样特征的数据元素的集合,成为顶点集。
数据关系R:
R={VR}
VR={
根本操作:
1)GreateGraph(&G,V,VR〕
初始条件:
v是图的顶点集,VR是图中弧的集合。
操作条件:
按V和VR的定义构造图G。
2)LocateVex(G,u)
初始条件:
图G存在,u和G中顶点有一样的特征。
操作条件:
假如G中存在顶点U,如此返回该顶点在图中的位置,如此返回其它信息。
3〕DestoryGraph(&u);
初始条件:
图G存在。
操作结果:
销毁图G。
4〕GetVex(G,v);
初始条件:
图G存在,v是图中某个顶点。
操作结果:
返回v的值。
5〕NextAdjVex(G,v,w);
初始条件:
图G存在,v是图中某个顶点,w是v的邻接顶点。
操作结果:
返回v的〔相对于w的〕下一个邻接顶点。
假如w是v的最后一个邻接点,如此返回“空〞。
6〕BFSTraverse(G,Visit());
初始条件:
图G存在,Visit是顶点的应用函数。
操作结果:
对图进展广度优先遍历。
在遍历过程中对每个顶点调用函数Visit一次且仅一次。
一旦visit()失败,如此操作失败。
存储结构
Typedefstruct
{
intadj;
intweight;
}AdjMatrix[MAX][MAX];
Typedefstruct
{
djMatrixarc;
intvexnum,arum;
}MGraph;
流程图,如下列图:
2.5.2方法描述
#deleteint_max10000/*节点不可达的距离*/
#definemax20/*数组最大长度*/
IntcreatMGraph_L(MGraph_L&G)//用邻接矩阵存储
Void1jjzprint(MGraph_LG)//输出邻接矩阵0
Intcreatadj(algraph&gra,MGraph_LG)//用邻接表存储图
Voidadjprint(algraphgra)//输出邻接表
Intprim(intg[][max],intn)//prim算法
Voidkruscal_are(MGraph_LG,algraphgra)//最小生成树kruscal算法
在该函数中主要有五段代码块,分别是主函数代码块、邻接矩阵定义模块代码、创建矩阵模块代码、最小生成树Prim算法与代价模块代码与最小生成树kruskal算法与代价模块代码,五段代码块分别有着不同的作用,共同满足了课题所需要实现的功能。
1)主函数模块代码
algraphgra;MGraph_LG;inti,d,g[20][20];
chara='a';d=creatMGraph_L(G);vnodev;
cout< 假如该图为非强连通图(含有多个连通分量)时"< <<"最小生成树不存在,如此显示为非法值"< cout<<"…………………菜单……………………"< cout<<"0、显示该图的邻接矩阵……………………"< cout<<"1、最小生成树PRIM算法与代价…………………"< ints;chary='y'; while(y='y'){cout<<"请选择菜单: "< switch(s){ case0: cout<<"邻接矩阵显示如下: "< case1: for(i=0;i! =G.vexnum;++i) for(intj=0;j! =G.vexnum;++j)g[i+1][j+1]=G.arcs[i][j].adj; cout<<"prim: "< cout< y/n: ";cin>>y;if(y=='n')break;} } 该主函数用一个循环语句,来执行其它的函数的功能。 从键盘输入顶点数和边数上限,再调用定义连接矩阵的函数,后输出创建连接矩阵的信息,再调用creatMGraph〔〕函数,接着进入菜单,然后再选择输入一个数确定是要输出连接矩阵还是最小生成树与代价,最后选择输入确定字母y或N确定是否继续。 2)邻接矩阵定义模块代码 typedefstructArcCell{ intadj;char*info; }ArcCell,AdjMatrix[20][20]; typedefstruct{ charvexs[20];AdjMatrixarcs; intvexnum,arum; }MGraph_L; intlocalvex(MGraph_LG,charv) {inti=0;while(G.vexs[i]! =v){++i;}returni;} 用typedefstruct定义连接矩阵,通过二维数组来存储连接矩阵,并设定参数的最大值为20。 3)创建矩阵模块代码 intcreatMGraph_L(MGraph_L&G) {charv1,v2;inti,j,w; cout<<"…………创建无向图〔城市分布图〕…………"< (46)不包括“()〞"< cin>>G.vexnum>>G.arum; for(i=0;i! =G.vexnum;++i) {cout<<"输入顶点〔城市〕"<>G.vexs[i];} for(i=0;i! =G.vexnum;++i) for(j=0;j! =G.vexnum;++j) {G.arcs[i][j].adj=int_max;G.arcs[i][j].info=NULL;} for(intk=0;k! =G.arum;++k) {cout<<"输入一条边依附的顶点〔城市〕和权〔距离〕: (ab3)不包括“()〞"< i=localvex(G,v1);j=localvex(G,v2); G.arcs[i][j].adj=w;G.arcs[j][i].adj=w;} cout<<"图G邻接矩阵创建成功! "< 该语句是从键盘输入顶点数和边数,输入顶点和权值,通过循环语句的调用,最后调用creatMGraph_L〔〕创建连接矩阵。 4)最小生成树Prim算法与代价模块代码 intprim(intg[][max],intn){ intlowcost[max],prevex[max];inti,j,k,min;intsum=o; for(i=2;i<=n;i++){lowcost[i]=g[1][i];prevex[i]=1;} lowcost[1]=0;for(i=2;i<=n;i++)//形成n-1条边的生成树 {min=inf;k=0; for(j=2;j<=n;j++) if((lowcost[j] =0)){min=lowcost[j];k=j;} printf("(%d,%d)%d\t",prevex[k]-1,k-1,min); sum+=min;lowcost[k]=0; for(j=2;j<=n;j++)if(g[k][j] {lowcost[j]=g[k][j];prevex[j]=k;} printf("\n");} cout<<"最少生成树的代价: ";cout< 该语句运用一系列的循环语句来实现的,利用前面的创建好的矩阵,通过各边权值的比拟,最后调用prim()函数,实现最小生成树的生成,同时运用sum把最小生成树各边权值相加得到最小生成树的代价。 5)最小生成树kruskal算法与代价模块代码 voidMiniSpanTree(MGraphA*D)//生成最小生成树 {inti,j,n,m,SUM=0;intk=1; intparent[M];edgeedges[M]; for(i=1;i {for(j=i+1;j<=D->vexnum;j++){if(D->arc[i][j].adj==1) {edges[k].begin=i;edges[k].end=j; edges[k].weight=D->arc[i][j].weight;k++;} } } sort(edges,D); for(i=1;i<=D->arum;i++) {parent[i]=0;} printf("最小生成树为: \n"); for(i=1;i<=D->arum;i++)//核心局部 {n=Find(parent,edges[i].begin);m=Find(parent,edges[i].end); if(n! =m){parent[n]=m; printf("<<%d,%d>>%d\n",edges[i].begin,edges[i].end,edges[i].weight); SUM=SUM+edges[i].weight;} } cout<<"最少生成树的代价: ";cout< 该语句运用一系列的循环语句来实现的,利用前面的创建好的矩阵,通过各边权值的比拟,最后调用MiniSpanTree()函数,实现最小生成树的生成,同时运用sum把最小生成树各边权值相加得到最小生成树的代价。 第三章详细设计说明 3.1主函数模块 首先用creatMGaph_L()函数进展邻接矩阵的初始化,然后调用creatadj()进展邻接表的初始化,然后根据用户输入判断switch()调用哪个模块。 3.2邻接表输出子模块 判断否超出了数据的个数,如果没有如此输出邻接表的头结点,如果头结点的指针域不为空如此输出下一个表节点,以此类推。 3.3邻接矩阵输出子模块 是否超出了数据的个数,如果没有如此输出G.arcs[i][j].adj中的值。 3.4创建邻接矩阵子模块 输入顶点和弧的个数,在输入顶点与顶点之间的权值,生成邻接矩阵。 prim子模块 标志顶点1参加U集合,形成n-1条边的生成树,寻找满足边的一个顶点在U,另一个顶点在V中的最小边,顶点K参加U,修改由顶点K到其他顶点边的权值,最后得到最小生成树。 3.6kruscal子模块 确定弧的结点,以与弧的权,比拟弧的权的大小并对权小的赋值,确定结点的位置,确保不能生成换,最后的到最小生成树。 第四章调试分析与体会 程序完成了prim和kruscal求一个图的最小生成树,并对图以邻接表和邻接矩阵的形式进展存储。 4.2出现的问题与解决方案 1)数据之间类型不同,引发数据间交换紊乱。 指针空间未分配导致系统随机给出一个错误的数据 2)在寻找下一个结点时,寻找到最小权值边,将其两端的顶点信息与变的权值存储道辅助数组中。 在设计解决这些问题时用多个for循环嵌套查找,判断。 3)一些小细节尤其要注意,比如变量的定义,定义的位置。 程序中对于一些没有最小生成树的图,没有判断功能。 还有就是进展完一个图的运 在做的过程中遇到的问题: 1、问题一: 求出图中的最小值 现象: 求出的最小值是0 原因: 图中没有连通的两个顶点之间的权值赋值为0 2、问题二: 求最小生成树时,else语句需再调用一个函数 现象: 对某些二叉树能求出最小生成树,但不能普遍适应 原因: 对于找最小生成树边的各种可能没有考虑全面,代码才没有广泛的适应性 3、问题三: 两个顶点之间的边是否是最小生成树的边 现象: 代码的功能不能分辨出是否是最小生成树的边 原因: 把简单的代码写的很复杂,从而杂乱无章出现错误 五、运行结果 将程序员录入后,让其运行。 将会出现一个菜单的界面,执行各种操作均有其对应的代码。 要执行何种操作只需输入对应的指令即可进展,在每步操作后均会有相应的提示。 运行程序后出界面,运行结果如如下图所示: 图5.1初界图面 选取选项1进展操作,运行结果如下列图: 图5.2建立邻接矩阵运行图 依据提示,分别输入无向图的顶点个数与弧的个数,然后依次输入各个顶点所对应的符号与与各个顶点相关联的弧与权值,存在邻接矩阵中。 假如选取选项3,运行结果如如下图所示: 图5.3求得最小生成树运行图 图中显示了求得最小生成树所对应的边、权值与最小生成树的代价 完毕语 通过这次课程设计,我收获了不少的东西。 我选择的题目是最小生成树,这个问题看这简单,但是做起来有非常大的困难。 平时我们很注重理论学习,但现在看来,实践也是非常重要的,两者缺一不可。 在这期间我遇到了不少的问题,问同学,查资料,虽然过程是辛苦琐碎的,但最后成果出来还是很鼓舞人心的。 经过我们不懈的努力我们终于完成了本次课程设计,通过这次课程设计,我感觉到要真正做出一个程序并不很容易,但只要用心去做,总会有收获,特别是当我遇到一个问题,想方法去解决,最后终于找到方法时,心里的那份喜悦之情真是难以形容。 编写程序中遇到问题再所难免,应耐心探究其中的原因,从出现问题的地方起,并联系前后程序,仔细推敲,逐个排查。 直到最终搞清为止。 我们本次做的是图的做小生成树问题,深刻的体会到它的实用性。 通过本次课程设计我们发现我们对于C语言和数据结构还有很多地方不知道,今后需要努力学习。 通过这次的课程设计过程我到了许多知识,这也是在大学里到目前为止完成的比拟完整的一个项目,虽然过程中遇到了许多困难,在同学和教师的帮助下一一克制了。 通过不断的发现问题,总结问题和解决问题的过程,使我在此次课程设计活动中不断的提高,和得到了宝贵的经验。 最后,我最想感的是教师这一学期来为我们辛勤的传授课业知识以与适时地讲解以与细心的指导。 我们会谨遵您的教诲,将您授予的知识学以致用,将您告诉我们的人生哲理作为我们人生道路的指路明灯。 通过本次课程设计,使我理解和掌握了很多实用的东西,在此我表衷心的感! 参考文献 [1].计算机专业课程设计中的需求分析[J].集美大学学报,2009,10 (2): 89—92. [2].高一凡.数据结构算法实现与解析[M].: 电子科技大学,2002 [3].Pascal之父NiklausWirth《算法+数据结构=程序》科学2001 [4].运霖《数据结构与算法》中南工业大学2002 [5].徐宝文志谭浩强《C程序设计语言》(第二版·新版)C++程序设计机械工业2004 [6].Shaffer《数据结构与算法分析》(C++版、JAVA版)电子工业1999 附录 源代码 #include #include #include //usingnamespacestd; #defineint_max10000 #defineinf9999 #definemax20 typedefstructArcCell{ intadj; char*info; }ArcCell,AdjMatrix[20][20]; typedefstruct{ charvexs[20];//定义一个顶点数组 AdjMatrixarcs;//定义一个邻接矩阵 intvexnum; intarum; }MGraph_L; intlocalvex(MGraph_LG,charv){ inti=0; while(G.vexs[i]! =v){ ++i; } returni; } intcreatMGraph_L(MGraph_L&G){ charv1,v2; inti,j,w; cout<<"请输入城市个数和总道路的个数: "< cin>>G.vexnum>>G.arum; for(i=0;i! =G.vexnum;++i){ cout<<"输入城市名"< cin>>G.vexs[i]; } for(i=0;i! =G.vexnum;i++) for(j=0;j! =G.vexnum;++j){ G.arcs[i][j].adj=int_max; G.arcs[i][j].info=NULL; } for(intk=0;k! =G.arum;++k){ cout<<"请输入两城市之间的距离: "< cin>>v1>>v2>>w;//输入一条边依附的两点与权值 i=localvex(G,v1); j=localvex(G,v2); G.arcs[i][j].adj=w; //G.arcs[j][i].adj=w; } cout<<"***********************************************"< cout<<"图创建成功"< cout<<"请根据如下进展操作"< returnG.vexnum; } voidljjzprint(MGraph_LG){//输出邻接矩阵 inti,j; for(i=0;i! =G.vexnum;++i){ for(j=0;j! =G.vexnum;++j) if(G.arcs[i][j].adj==10000) {cout<<"0"<<"";} else { cout< }cout< } } typedefstructarode{//定义表结点 intadjvex;//该弧指向的顶点在图中的位置 structarode*nextarc
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 最小 生成 解决 实际问题 课程设计