《最小生成树数据结构课程设计报告(共17页).doc》由会员分享,可在线阅读,更多相关《最小生成树数据结构课程设计报告(共17页).doc(17页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上河北科技大学课程设计报告学生姓名:白云 学 号: Z 专业班级: 计算机113班 课程名称: 数据结构课程设计 学年学期: 2 01 32 014学年第2学期 指导教师: 郑 广 2014年6月课程设计成绩评定表学生姓名白云学 号Z成绩专业班级计算机113起止时间2014.6.232014.6.27设计题目指导教师评语学习态度出勤情况: 好 较好 一般 较差 课 题 工 作 量: 饱满 较大 合理 较小 综合运用知识能力: 好 较好 一般 较差 方 案 设 计 情况: 合理 较合理 基本合理 不合理 课题结果分析能力: 强 较强 一般 较差 设 计 实 现 情况: 全
2、部 大部分 部分 未实现 设 计 报 告 内容: 详细 完整 较完整 不完整 设计报告文档格式: 规范 较规范 基本规范 不规范 独 立 动 手 能力: 强 较强 一般 较差 指导教师: 年 月 日目 录专心-专注-专业一、需求分析说明1.1最小生成树总体功能要求在n个城市之间建设网络,只需保证连通即可,求最经济的架设方法。存储结构采用多种。求解算法多种。1.2基本功能在n个城市之间建设网络,只需要架设n-1条线路,建立最小生成树即可实现最经济的架设方法。程序可利用克鲁斯卡尔算法或prim算法生成最小生成树。1.3 模块分析主模块:用于生成界面和调用各个子模块。Kruscal模块:以krusc
3、al算法实现最小生成树。Prim模块:以prim算法实现最小生成树。邻接表模块:用邻接表方式存储图。邻接表输出模块:输出邻接表。邻接矩阵模块:用邻接矩阵方式存储图。邻接矩阵模块:输出邻接矩阵。 二、概要设计说明2.1设计思路问题的解决分别采用普利姆算法以及克鲁斯卡尔算法。1) 普利姆算法就是先选择根,把它放入一个集合U中,剩余的顶点放在集合V中。然后选择该顶点与V中顶点之间权值最小的一条边,以此类推,如果达到最后一个则返回上一个顶点。2) 克鲁斯卡尔算法就是写出所有的顶点,选择权最小的边,然后写出第二小的,以此类推,最终要有一个判断是否生成环,不生成则得到克鲁斯卡尔的最小生成树。2.2模块调用
4、图 主模块 Kruscal模块 Prim模块邻接表输出模块邻接矩阵输出模块邻接表模块邻接矩阵模块2.3数据结构设计2.3.1.抽象数据类型ADT Graph 数据对象 V:v是具有相同特征的数据元素的集合,成为顶点集。数据关系 R:R=VR VR=|v,w属于v且p(v,w)表示从v到w的弧,谓词p(v,w)定义了弧的意义或信息基本操作:1) GreatGraph(&G,V,VR) 初始条件:V是图的顶点集,VR是图中弧的集合。 操作条件:按V和VR的定义构造图G。2) LocateVex(G,u) 初始条件:图G存在,u和G中顶点有相同的特征。 操作条件:若G中存在顶点u,则返回该顶点在图中
5、的位置,否则返回其他信息。 2.3.2方法描述#define int_max 10000 /*节点不可达的距离*/#define max 20 /*数组最大长度*/int creatMGraph_L(MGraph_L &G) /用邻接矩阵存储void ljjzprint(MGraph_L G) /输出邻接矩阵int creatadj(algraph &gra,MGraph_L G) /用邻接表存储图void adjprint(algraph gra) /输出邻接表int prim(int gmax,int n) /prim算法void kruscal_arc(MGraph_L G ,algra
6、ph gra) /最小生成树kruscal算法 三、详细设计说明3.1主函数模块首先调用creatMGraph_L()函数进行邻接矩阵的初始化,然后调用creatadj()函数进行邻接表的初始化,然后根据用户输入判断switch()调用哪个模块。3.2邻接表输出子模块首先判断是否超出了数据的个数,如果没有则输出邻接表的头节点,如果头节点的指针域不为空则输出下一个表结点,以此类推。3.3邻接矩阵输出子模块判断是否超出了数据的个数,如果没有则输出G.arcsij.adj中的值。3.4创建邻接矩阵子模块输入顶点和弧的个数,再输入顶点与顶点之间的权值,生成邻接矩阵3.5创建邻接表子模块根据表结构定义一
7、个表,设置表头结点为空,再循环生成其它结点并连接到上一个结点的后面。3.6 Prim子模块标志顶点1加入U集合,形成n-1条边的生成树,寻找满足边的一个顶点在U,另一个顶点在V中的最小边,顶点K加入U,修改由顶点K到其他顶点边的权值,最后得到最小生成树。3.7 Kruscal子模块确定弧的结点,以及弧的权,比较弧的权的大小并对权小的赋值,确定结点的位置,确保不能生成换,最后的到最小生成树。 四、调试分析4.1实际完成情况说明程序完成了prim和kruscal求一个图的最小生成树,并对图以邻接表和邻接矩阵的形式进行存储。4.2 出现的问题及解决方案1)数据之间类型不同,引发数据间交换紊乱。指针空
8、间未分配导致系统随机给出一个错误的数据2)在寻找下一个结点时,寻找到最小权值边,将其两端的顶点信息及变的权值存储道辅助数组中。在设计解决这些问题时用多个for循环嵌套查找,判断。3)一些小细节尤其要注意,比如变量的定义,定义的位置。4.3程序中可以改进的地方程序中对于一些没有最小生成树的图,没有判断功能。还有就是进行完一个图的运算要关闭程序再重新输入新的图。 五、用户使用说明输入正确的数据程序执行菜单邻接矩阵存储邻接表存储Prim算法Kruscal算法 六、课程设计总结通过这次课程设计,我收获了不少的东西。我选择的题目是最小生成树,这个问题看这简单,但是做起来有非常大的困难。平时我们很注重理论
9、学习,但现在看来,实践也是非常重要的,两者缺一不可。在这期间我遇到了不少的问题,问同学,查资料,虽然过程是辛苦琐碎的,但最后成果出来还是很鼓舞人心的。 七、测试数据1:城市的个数和线路个数:5,62:各个城市的名称:a,b,c,d,e3:每条路径的权值:a d 1 , a b 1 , b c 1 , b d 1 , d e 1 , c e 2 八、参考书目1汤文兵.数据结构.北京:清华大学出版社,20112李春葆.数据结构习题与解析.北京:清华大学出版社,20103Mark Allen Weiss. Data Structures and Algorithm Analysis in C: Se
10、cond Edition. New York:MITPress, 20074郭翠英.C语言课程设计案例精编.北京:中国水利出版社,2011源代码#include #include #include /using namespace std;#define int_max 10000#define inf 9999#define max 20typedef struct ArcCellint adj;char *info;ArcCell,AdjMatrix2020;typedef struct char vexs20;/定义一个顶点数组AdjMatrix arcs;/定义一个邻接矩阵int ve
11、xnum; int arcnum;MGraph_L;int localvex(MGraph_L G,char 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请输入城市个数和总道路的个数:G.vexnumG.arcnum;for(i=0;i!=G.vexnum;+i)cout输入城市名i+1G.vexsi;for(i=0;i!=G.vexnum;i+)for(j=0;j!=G.vexnum;+j)G.arcsij.adj=int_max;G.arc
12、sij.info=NULL;for(int k=0;k!=G.arcnum;+k)cout请输入两城市之间的距离:v1v2w;/输入一条边依附的两点及权值i=localvex(G,v1);j=localvex(G,v2);G.arcsij.adj=w;/G.arcsji.adj=w;cout*endl; cout图创建成功endl; cout请根据如下进行操作endl;return G.vexnum;void ljjzprint(MGraph_L G)/输出邻接矩阵int i,j;for(i=0;i!=G.vexnum;+i)for(j=0;j!=G.vexnum;+j)if(G.arcsij
13、.adj=10000)cout0 ;elsecoutG.arcsij.adj ;coutendl;typedef struct arcnode /定义表结点int adjvex;/该弧指向的顶点在图中的位置struct arcnode *nextarc;/链域,指向下一条边或弧的结点char *info;/该弧的信息arcnode;typedef struct vnode/临街链表顶点头结点char data;/数据arcnode *firstarc;/链域vnode,adjlist;typedef struct /表的定义adjlist verticesmax;/定义头结点int vexnu
14、m,arcnum;/图的当前顶点数和弧数int kind;/图的种类标志algraph;typedef struct acr/弧的定义int pre;/弧的一结点int bak;/弧的另一结点int weight;/弧的权edg;int creatadj(algraph &gra,MGraph_L G)/用邻接表存储图int i=0,j=0;arcnode *arc,*tem,*p;for( i=0;i!=G.vexnum;+i)/邻接表的初始化gra.verticesi.data=G.vexsi;/将abcde放入顶点信息域gra.verticesi.firstarc=NULL;/指针域为空
15、for( i=0;iG.vexnum;i+)for( j=0;jG.vexnum;j+)if(gra.verticesi.firstarc=NULL)if(G.arcsij.adj!=int_max&jadjvex=j; gra.verticesi.firstarc=arc; arc-nextarc=NULL; p=arc; elseif(G.arcsij.adj!=int_max&j!=G.vexnum)tem=(arcnode *)malloc(sizeof(arcnode); tem-adjvex=j; p-nextarc=tem; tem-nextarc=NULL; p=tem;gra
16、.vexnum=G.vexnum;gra.arcnum=G.arcnum;return 1;void adjprint(algraph gra)/输出邻接表int i;for(i=0;i!=gra.vexnum;+i)arcnode *p;coutgra.verticesi.datai;p=gra.verticesi.firstarc;while(p!=NULL)coutadjvex;p=p-nextarc;coutendl;typedef struct int adjvex; int lowcost;closedge;int prim(int gmax,int n)/prim算法 int l
17、owcostmax,prevexmax;/lowcost存储当前集合U分别到剩余结点的最短路径prevex存储最短路径在U中的结点 int i,j,k,min; for(i=2;i=n;i+) lowcosti=g1i;/初始化 prevexi=1;/顶点未加入到最小生成树中 lowcost1=0;/标志顶点1加入U集合 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
18、,min); lowcostk=0;/顶点K加入U for(j=2;j=n;j+) if(gkj0) f=arcvisitedf;return f;void kruscal_arc(MGraph_L G ,algraph gra) /最小生成树kruscal算法edg edgs20;int i,j,k=0;for(i=0;i!=G.vexnum;+i)for(j=i;j!=G.vexnum;+j)if(G.arcsij.adj!=10000)edgsk.pre=i;edgsk.bak=j;edgsk.weight=G.arcsij.adj;+k;int x,y,m,n;int buf,edf;
19、for(i=0;i!=gra.arcnum;+i)arcvisitedi=0;for(j=0;j!=G.arcnum;+j) m=10000; for(i=0;i!=G.arcnum;+i) if(edgsi.weightm) m=edgsi.weight; x=edgsi.pre; y=edgsi.bak; n=i; buf=find(arcvisited,x); edf=find(arcvisited,y); edgsn.weight=10000; if(buf!=edf) arcvisitedbuf=edf; cout(x,y)m; coutendl; void main()algrap
20、h gra;MGraph_L G;int i,j,d,g2020;char a=a;d=creatMGraph_L(G);creatadj(gra,G);cout*endl;cout*1.用邻接矩阵存储:*endl;cout*2.用邻接表存储:*endl;cout*3.PRIM算法实现:*endl;cout*4.KRUSCAL算法实现:*endl;int s;char y=y;while(y=y)cout请选择菜单:s;switch(s)case 1:cout用邻接矩阵存储为:endl;ljjzprint(G);break;case 2: cout用邻接表存储为:endl; adjprint(gra); break;case 3: for(i=0;i!=G.vexnum;+i) for(j=0;j!=G.vexnum;+j) gi+1j+1=G.arcsij.adj; coutPRIM算法最经济的架设方法为:endl; prim(g,d); break; case 4: coutKRUSCAL算法最经济的架设方法为:endl; kruscal_arc(G,gra); break;coutendly;if(y=n)break;