1、 数据结构课程设计报告数据结构课程设计报告 7046135(此文档为 word格式,下载后您可任意编辑修改!)数据结构课程设计报告 院系:计算机学院 班级:软件 121班 姓名:程猛 学号:题目:最小生成树 指导老师:杜献峰 一、引言 3 二、设计题目 3 1.问题描述 3 2.系统要求 3 3.测试数据 4 4.实现提示 4 5.参考文献 4 6.运行环境 5 三、需求分析 5 1.如何选择存储结构去建立一个带权网络。5 2.如何在所选存储结构下输出这个带权网络。5 3.如何实现 PRIM 算法和 Kruskal 算法的功能。5 4.如何从每个顶点开始找到所有的最小生成树的顶点。6 5.如何
2、输出最小生成树的边及其权值。6 四、概要设计 6 2.图的存储结构 7 3.流程图 7 五、详细设计 8 1.主函数模块 8 2.对路径权值进行排序 9 六、调试与分析 13 七、测试结果 16 八、设计心得体会 16 附录(源代码)17 摘要 最小生成树是数据结构中图的一种重要应用,在图中对于 n 个顶点的连通网可以建立许多不同的生成树,最小生成树就是在所有生成树中总的代价最小的生成树。本课程设计是以邻接矩阵作为图的存储结构,分别采用 Prim和 Kruskal 算法求最小生成树。Kruskal 算法和 Prim算法是求最小生成树的常用算法它们分别适用于稠密图和稀疏图。最小生成树的应用非常的
3、广,如矿井通风设计和改造最优化方面以及如何搭建最短的网络线缆,构建造价最低的通讯网络。一、引言一、引言 本课程设计我们要解决的问题是图最小生成树问题。要用到图的先相关数据结构和求最小生成树的两种数据结构算法普里姆算法和克鲁斯卡尔算法,以及储存图的边和点的邻接矩阵。本课程设计要解决的问题构造连通网的最小生成树,我们首先要做的是创建一个邻接矩阵,用以来存储图,然后我们要想好怎样利用普里姆算法和克鲁斯卡尔算法来构造最小生成树。把这两种算法写入主函数,调试好程序。最后写好报告。二、设计题目二、设计题目 1.问题描述问题描述 若要在 n个城市之间建设通信网络,只需要假设 n-1条线路即可。如何以最低的经
4、济代价建设这个通信网,是一个网的最小生成树问题。2.系统要求系统要求 利用克鲁斯卡尔算法求网的最小生成树。利用普里姆算法求网的最小生成树。要求输出各条边及它们的权值。3.测试数据测试数据 4.实现提示实现提示 通信线路一旦建成,必然是双向的。因此,构造最小生成树的网一定是无向图。设图的顶点数不超过 30个,并为简单起见,网中边的权值设成小于 100的整数,100则表示没有路径。5.参考文献参考文献 1 严蔚敏.数据结构(C语言版)M.北京:清华大学出版社,1997.2 谭浩强.C程序设计(第三版)M.北京:清华大学出版社,2005.1.3 二霍红卫算法设计与分析西安西安电子科技大学出版社,20
5、05.4 陈杰.计算机专业课程设计中的需求分析J.集美大学学报,2009,10(2):8992.5 高一凡.数据结构算法实现及解析M.西安:西安电子科技大学出版社,2002 6.运行环境运行环境 VC+6.0 三、需求分析三、需求分析 1.如何选择存储结构去建立一个带权网络。如何选择存储结构去建立一个带权网络。此问题的关键在于如何实现 PRIM 算法和 Kruskal 算法,实现的过程中如何得到构成最小生成树的所有顶点,此外输出也是一个关键问题所在,在此过程中经过了多次调试。2.如何在所选存储结构下输出这个带权网络。如何在所选存储结构下输出这个带权网络。将图中的所有顶点存储到一个一维数组中,通
6、过一个二维数组用邻接矩阵连实现对各边权值的存储 3.如何实现如何实现 PRIM 算法和算法和 Kruskal 算法的功能。算法的功能。首先我们对 prim算法的问题进行大致的概要分析:假设 N=(V,E)是连通网,TE是 N上最小生成树中边的集合。算法从U=u0(u0V),TE=开始,重复执行下述操作:在所有 uU,vV-U的边(u,v)E中找一条代价最小的边(u0,v0)并入集合 TE,同时 v0并入 U,直至U=V为止。此时 TE中必有 n-1条边,则 T=(V,TE)为 N的最小生成树。克鲁斯卡尔算法从另一种途径求网的最小生成树:假设连通网 N=(V,E),则另最小生成树的初始状态为只有
7、 n个顶点而无边的非连通图 T=(V,),图中每个顶点自成一个连通分量。在 E中选择代价最小的边若该边依附的顶点落在 T中不同的连通分量上,则将此边加入到 T中,否则舍去此边而选择下一条代价最小的边。以此类推直至 T中的所有顶点都在同一连通分量上为止。4.如何从每个顶点开始找到所有的最小生成树的顶点。如何从每个顶点开始找到所有的最小生成树的顶点。对于 prim算法从图的点集中任取一个顶点作为起始顶点,然后找到依附于该顶点的所有边选取权值最小的,依次找下去直至图中所有顶点都在一个点集中为止。对于克鲁斯卡尔算法则通过对权值进行排序找出权值最小的顶点和边并把该边的顶点并入点集之中。5.如何输出最小生
8、成树的边及其权值。如何输出最小生成树的边及其权值。通过访问数组来实现对最小生成树边和权值的输出。四、概要设计四、概要设计 1、设定图的抽象数据类型:ADT Graph 数据对象 V:V是具有相同特性的数据元素的集合,称为点集.数据关系 R:R=VR VR=(v,w)|v,w属于 V,(v,w)表示 v和 w之间存在的路径 基本操作 P:CreatGraph(&G,V,VR)初始条件:V是图的顶点集,VR是图中弧的集合.操作结果:按 V和 VR是定义构造图 G.Sort(edge*,MGraph*)初始条件:图 G存在,各边权值已知;操作结果:对权值进行排序;Find(int*,int)初始条件
9、:前者为已存在的集合,后者为集合中的元素;操作结果:查找函数,确定后者所属子集;Swapn(edge*,int,int)初始条件:图 G存在,各边权值已知;操作结果:交换某两个边的权值;2.图的存储结构图的存储结构 typedef struct int vexnum,arcnum;ALGraph;typedef struct/边的结构体定义 int begin,end;/边的开始和结束顶点 int cost;/权值 EDGE;typedef struct int edgesmaxmax;/int n,e;MGraph;3.流程图流程图 五、详细设计五、详细设计 在该函数中有 6个模块,分别是主
10、函数模块、路径权值进行排序、交换顶点及权值模块、判断是否回环、prim算法的实现、Kruskal 算法的实现。1.主函数模块主函数模块 ALGraph G;MGraph G2;int v,i,j;char a;do system(cls);coutt*nn;coutt 1 克鲁斯卡尔 n;coutt 2 普 里 姆 n;coutt 3 退 出 nn;coutt*n;couta;switch(a)case 1:MiniSpanTree_Kruskal(G);system(pause);break;case 2:coutG2.n;for(j=1;j=G2.n;j+)cout请输入第j个顶点所有边的
11、权值(100代表不连通):;for(i=1;iG2.edgesji;coutv;MiniSpanTree_PRTM(G2,v);system(pause);break;default:break;while(a!=3);return 0;该模块包含菜单的设计以及通过一个 switch 语句来实现对 prim算法和 Kruskal 算法的实现。进入主菜单后选择相应的序号执行相应的操作,每进行一步后,按任意键继续进行下一个操作可重复执行。2.对路径权值进行排序对路径权值进行排序 void Sort(EDGE*edges,ALGraph G)/对带权路径从小到大排序 int i,j;for(i=1;
12、i=G.arcnum;i+)for(j=i;jedgesj.cost)Swapn(edges,i,j);在图中找到权值最小的边 3.交换顶点及权值 void Swapn(EDGE*edges,int i,int j)/交换的两个顶点及权值 int temp;temp=edgesi.begin;edgesi.begin=edgesj.begin;edgesj.begin=temp;temp=edgesi.end;edgesi.end=edgesj.end;edgesj.end=temp;temp=edgesi.cost;edgesi.cost=edgesj.cost;edgesj.cost=te
13、mp;该模块主要用于 Kruskal 算法,找到图中权值最小的一条边,然后交换它们的顶点和权值。4.判断是否回环 int Find(int*parents,int f)/判断是否形成环 while(parentsf)0&(f!=parentsf)f=parentsf;return f;在 Kruskal算法中初始 parents为 0来设置访问未访问标志,以此来判断图是否成环。5.prim算法的实现 void MiniSpanTree_PRTM(MGraph&G,int v)int closedgemax;int lowcostmax;int i,j,k,min;for(i=1;i=G.n;i
14、+)lowcosti=G.edgesvi;closedgei=v;for(i=1;iG.n;i+)min=INF;for(j=1;j=G.n;j+)if(lowcostj!=0&lowcostjmin)min=lowcostj;k=j;printf(边(%d,%d)权为:%dn,closedgek,k,min);lowcostk=0;for(j=1;j=G.n;j+)if(G.edgeskj!=0&G.edgeskjlowcostj)lowcostj=G.edgeskj;closedgej=k;6.Kruskal 算法的实现 void MiniSpanTree_Kruskal(ALGraph&
15、G)/MiniSpanTree_Kruskal()函数实现 int i,s,v1,v2,value,bnf,edf;int parentsMAX_VERTEX_NUM;EDGE edgesMAX_VERTEX_NUM;coutendlG.vexnum;/输入顶点数 coutG.arcnum;/输入边数 cout请输入(V1和 V2),例如:(V1=1,V2=3),(V1=2,V2=4).;coutendl;/输入 arc(v1,v2)for(i=1;i=G.arcnum;+i)coutendl请输入第 iv1;/输入头顶点 cout请输入第 iv2;/输入尾顶点 cout请输入第 ivalue
16、;/输入边的权值 edgesi.begin=v1;edgesi.end=v2;while(v1G.vexnum|v2G.vexnum)/如果输入的非法,重新输入 cout输入不合法,请重新输入!;coutendl请输入第 iv1;cout请输入第 iv2;cout请输入第 ivalue;edgesi.begin=v1;edgesi.end=v2;edgesi.cost=value;Sort(edges,G);/调用 Sort()函数 cout按照排列好的序列逐个输出权值endl;for(i=1;i=G.arcnum;i+)coutedgesi.costt;for(i=1;i=G.vexnum;+i)parentsi=0;/初始化 array parents coutendl最小生成树为:endl;for(i=1,s=1;s=G.vexnum&i=G.arcnum;i+)bnf=Find(parents,edgesi.begin);edf=Find(parents,edgesi.end);if(bnf!=edf)parentsbnf=edf;coutendledgesi.begin-;/
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1