




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、湖南人文科技学院计算机科学技术系 课程设计说明书 课程名称: _数据结构 _ 课程代码: _408024 _ 题 目:最小生成树问题 年级/专业/班:08级计算机科学与技术一班 学生姓名:肖禁 吴广 刘聪 邱建标 胡子龙 学 号:08408110 0840807 08408109 指导教师:袁辉勇 开题时间:2009 年 12 月 23 日 完成时间:2010 年 1 月 1 日1 / 20 摘要 . 2 一、弓I 言 3 二、设计目的与任务 3 1、 课程设计目的 . 3. 2、 课程设计的任务 . 3. 三、设计方案 4 1、 需求分析 . 4. 2、 概要设计 . 4. 3、 详细设计
2、. 5. 4、 程序活单 . 9. 四、 . 调试分析与体会 14 五、 . 运行结果 15 六、 . 结 论 162 / 20 摘要 最小生成树是数据结构中图的一种重要应用, 在图中对于n个顶点的连通网可以建立 许多不同的生成树,最小生成树就是在所有生成树中总的代价最小的生成树。 本课程设计 是以邻接矩阵作为图的存储结构,分别采用Prim和Kruskal算法求最小生成树。Kruskal 算法和Prim算法是求最小生成树的常用算法它们分别适用于稠密图和稀疏图。最小生成 树的应用非常的广,如矿井通风设计和改造最优化方面以及如何搭建最短的网络线缆 ,构 建造价最低的通讯网络。 关键词:最小生成树;
3、Kruskal算法;Prim算法 Abstract The minimum Cost spanning tree data structure is an important application of Chinese, in the picture for n vertex even TongWang can create many different spanning tree, minimum spanning tree is in all spanning tree in the total cost of the minimum spanning tree. This course
4、 is designed as a figure of the adjacency matrix storage structure, we adopt Prim and Kruskal minimum spanning tree algorithm. Kruskal Prim algorithm and minimum spanning tree algorithm is used for the algorithm respectively applicable and sparsely populated. Minimum spanning tree is very wide appli
5、cation in mines, such as the ventilation design and modification and optimization in how to set up the shortest cable network, constructing the lowest cost of communications network Keywords: Minimum Cost Spanning Tree; Kruskal algorithm ; Prim algorithm3 / 20 数据结构课程设计 - 最小生成树 一、 引言 数据结构是计算机科学与技术专业和
6、信息管理与信息系统专业的必修课之 一,是一门综合性的专业基础课。本课程较系统地介绍了软件设计中常用的数据结构 以及相应的实现算法,如线性表、栈、队列、树和二义树,图、检索和排序等,并对 性能进行分析和比较,内容非常丰富。 本课程设计我们要解决的问题是图最小生成树问题。 要用到图的先相关数据结构 和求最小生成树的两种数据结构算法普里姆算法和克鲁斯卡尔算法, 以及储存图的边 和点的邻接矩阵。 本课程设计要解决的问题构造连通网的最小生成树 ,我们首先要做的是创建一个 邻接矩阵,用以来存储图,然后我们要想好怎样利用普里姆算法和克鲁斯卡尔算法来 构造最小生成树。把这两种算法写入主函数,调试好程序。最后写
7、好报告。 二、 设计目的与任务 1、 课程设计目的 本课程设计的目的是了解并掌握数据结构与算法的设计方法, 具备初步的独立分 析和设计能力;初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基 本方法和技能;提高综合运用所学的理论知识和方法独立分析和解决问题的能力; 训 练用系统的观点和软件开发一般规范进行软件开发。 2、 课程设计的任务 问题描述:已知一个无向连通网表示n个城市以及城市间可能设置的通信线路, 其中网的顶点表示城市,边表示两个城市之间的线路,赋于边上的权值表示相应的代 价。对于n个点的连通网能建立许多不同的生成树,每一棵生成树都可以是一个通信 网。我们要选择一棵生成树,
8、使总的耗费最小。 4 / 20 三、设计方案 1、需求分析 1) 建立一个图,其存储方式可以采用邻接矩阵形式,需要定义两个数组,一个存储 顶点,一个存储边,存储边的数组表明节点间的连通关系和边的权值; 。 2) 利用普里姆算法和克鲁斯卡尔算法求网的最小生成树 3) 按顺序输出生成树中各条边以及它们的权值。 2、概要设计 1)抽象数据类型(ADT)如下: ADT Graph (数据对象V: v是具有相同特性的数据元素的集合,称为顶点集。 数据关系R: R=VR VR=|v,w 届于 v 且 p(v,w),(v,w)表示从 v 到 w 的弧,谓词 p(v,w) 定义了弧的意义或信息 基本操作: (
9、1) CreatGraph(&GV,VR); 初始条件:V是图的顶点集,VR是图中弧的集合。 操作结果:按V和VR的定义构造图Go (2) LocateVex(G u); 初始条件:图G存在,u和G中顶点有相同的特征。 操作结果:若G中存在顶点u,则返回该顶点在图中的位置;否则返回其他 信息。 (3) DestoryGraph(&u); 初始条件:图G存在。 操作结果:销毁图Go (4) GetVex(G v); 初始条件:图G存在,v是图中某个顶点。 操作结果:返回v的值。 (5) NextAdjVex(G, v, w); 初始条件:图G存在,v是图中某个顶点,w是v的邻接顶
10、点。 操作结果:返回v的(相对于w的)下一个邻接顶点。若w是v的最后一个 邻接点,贝U返回 空”。 (6) BFSTraverse(G Visit(); 初始条件:图G存在,Visit是顶点的应用函数。 操作结果:对图进行广度优先遍历。在遍历过程中对每个顶点调用函数 Visit 一次且仅一次。一旦visit()失败,则操作失败。 2) 存储结构 Typedef struct ( int adj; 5 / 20 int weight; AdjMatrixMAXMAX; Typedef struct ( djMatrix arc; int vexnum, arcnum; MGraph; 3) 流程
11、图 3、详细设计 在该函数中主要有五段代码块,分别是主函数代码块、邻接矩阵定义模块代码、创建 链接矩阵模块代码、最小生成树Prim算法及代价模块代码与最小生成树 kruskal算法及代 价模块代码,五段代码块分别有着不同的作用,共同满足了课题所需要实现的功能。 1)主函数模块代码 algraph gra; MGraph_L G; int i,d,g2020; char a=a; d=creatMGraph_L(G); vnode v; coutendl注意:若该图为非强连通图(含有多个连通分量)时endl 最小生成树不存在,则显示为非法值endlendl; 6 / 20 cout . 菜单 .
12、 endlendl; cout0、显示该图的邻接矩阵 . endl; coutv1、最小生成树 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(intj=0;j!=G .vexnum;+j) gi+1j+1=G .arcsij.adj; coutprim:endl; prim(g,d); break; coutendly; if(y=n
13、) break; 该主函数用一个循环语句,来执行其它的函数的功能。从键盘输入顶点数和边数 上限,再调用定义连接矩阵的函数,后输出创建连接矩阵的信息,再调用creatMGraph ()函数,接着进入菜单,然后再选择输入一个数确定是要输出连接矩阵还是最小生 成树及代价,最后选择输入确定字母 y或N确定是否继续。 2) 邻接矩阵定义模块代码 typedef struct ArcCell int adj; char *info; ArcCell,AdjMatrix2020; typedef struct char vexs20; AdjMatrix arcs; int vexnum,arcnum; M
14、Graph_L; int localvex(MGraph_L G,char v) ( int i=0; while(G.vexsi!=v) ( +i; return i; 7 / 20 用typedef struct定义连接矩阵,通过二维数组来存储连接矩阵,并设定参数的最 大值为20。 3) 创建链接矩阵模块代码 int creatMGraph_L(MGraph_L &G) ( char v1,v2; int i,j,w; cout . 创建无向图(城市分布图) . ”endl;cout ”请输入 图G顶点(城市)和弧(边)的个数:(4 6)不包括“()” G.vexnumG.arcn
15、um; for(i=0;i!=G.vexnum;+i) ( cout输入顶点(城市)iG.vexsi; for(i=0;i!=G.vexnum;+i) for(j=0;j!=G.vexnum;+j) ( Garcsij.adj=int_max; G=NULL; for(int k=0;k!=G .arcnum;+k) ( cout输入一条边依附的顶点(城市)和权(距离) :(a b 3)不包括 “()” ”v1v2w; i=localvex(G,v1); j=localvex(G,v2); G.arcsij.adj=w; G.arcsji.adj=w; cout图 G 邻
16、接矩阵创建成功! endl; return Gvexnum; 该语句是从键盘输入顶点数和边数,输入顶点和权值,通过循环语句的调用,最 后调用creatMGraph_L ()创建连接矩阵。 4) 最小生成树Prim算法及代价模块代码 int prim(int gmax,int n) ( int lowcostmax,prevexmax; int i,j,k,min;int sum=o; for(i=2;i=n;i+) ( lowcosti=g1i; prevexi=1; lowcost1=0; for(i=2;i=n;i+) 形成 n-1 条边的生成树 8 / 20 ( min=inf; k=0
17、; 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最少生成树的代价:; coutsum; return 0; 该语句运用一系列的循环语句来实现的,利用前面的创建好的链接矩阵,通过各 边权值的比较,最后调用prim()函数,实现最小生成树的生成
18、,同时运用 sum把最小 生成树各边权值相加得到最小生成树的代价。 5) 最小生成树kruskal算法及代价模块代码 void MiniSpanTree(MGraphA *D)/ 生成最小生成树 ( int i, j, n, m, SUM=0; int k = 1; int parentM; edge edgesM; for ( i = 1; i vexnum; i+) ( for (j = i + 1; j vexnum; j+)( if (D-arcij.adj = 1) ( edgesk.begin = i; edgesk.end = j; edgesk.weight = D-arcij
19、.weight; k+; sort(edges, D); for (i = 1; i arcnum; i+) ( parenti = 0; printf(最小生成树为:n”); for (i = 1; i arcnum; i+)/ 核心部分 ( n = Find(parent, edgesi.begin); m = Find(parent, edgesi.end); if (n != m)( parentn = m; 9 / 20 printf( %dn, edgesi.begin, edgesi.end, edgesi.weight); SUM=SUM+edgesi.weight; cout
20、最少生成树的代价:; coutSUM. 该语句运用一系列的循环语句来实现的,利用前面的创建好的链接矩阵,通过各 边权值的比较,最后调用MiniSpanTree ()函数,实现最小生成树的生成,同时运用sum 把最小生成树各边权值相加得到最小生成树的代价。 4、程序清单 #include #include using namespace std; #define int_max 10000 #define inf 9999 #define max 20 #define MAX 20 #define M 20 typedef struct ArcCell (int adj;char *info;
21、ArcCell,AdjMatrix2020; typedef struct (char vexs20;AdjMatrix arcs; int vexnum,arcnum; MGraph; int localvex(MGraph G,char v) (int i=0; while(G .vexsi!=v) (+i; return i; void ljjzprint(MGraph G) (int i,j,n=0; printf(建立的邻接矩阵如下:n); printf(n); printf(n); for(i=0;i!=G.vexnum;i+) (for(j=0;j!=G.vexnum;j+) (
22、if(j=0)printf( ); 10 / 20 printf(%d,G.arcsij.adj);printf( );n+; if(n=G.vexnum)( printf(n);n=0; printf(n); int creatMGraph(MGraph &G) (char v1,v2; int i,j,w; printf(建立邻接矩阵:n); printf(请输入图G顶点(城市)和弧(边)的个数:); scanf(%d,&G.vexnum); scanf(%d,&G.arcnum); printf(输入所有顶点:); for(i=0;iG.vexsi; for(i=
23、0;iG .vexnum;i+) for(j=0;jG .vexnum;j+) ( G.arcsij.adj=int_max; G.=NULL; printf(输入所有边及依附的顶点(城市)和权(距离):n); for(int k=0;kv1v2w; i=localvex(G,v1); j=localvex(G,v2); G.arcsij.adj=w; G.arcsji.adj=w; ljjzprint(G); printf(图G邻接矩阵创建成功! n); return Gvexnum; int visitedmax; int we; typedef struct arc
24、node int adjvex; struct arcnode *nextarc; char *info; arcnode; typedef struct vnode char data; arcnode *firstarc; vnode,adjlist; typedef struct/) 的定义 adjlist verticesmax; int vexnum, arcnum; int kind; algraph; int prim(int gmax,int n) / 最小生成树 PRIM 算法 int lowcostmax, prevexmax; int i,j,k,min; int sum
25、=0; for(i=2;i=n;i+) lowcosti=g1i; prevexi=1; lowcost1=0; for(i=2;i=n;i+) 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) owcostj=gkj;prevexj=k; printf(n); 11 / 20 cout最少生成树的代价
26、:; coutarcnum,&D-vexnum); for (i = 1; i vexnum; i+)/ 初始化图 for ( j = 1; j vexnum; j+) D-arcij.adj = D-arcji.adj = 0; for ( i = 1; i arcnum; i+)/ 输入边和权值 printf(n 请输入有边的 2 个顶点); scanf(%d %d,&n,&m); while(n D-vexnum | m D-vexnum) printf(-输入的数字不符合要求请重新输入:); scanf(%d%d,&n,&m); D-arcnm.
27、adj = D-arcmn.adj = 1; getchar(); printf(n 请输入 d 与%d 之间的权值:,n, m); scanf(%d,&D-arcnm.weight); printf(邻接矩阵为:n); for ( i = 1; i vexnum; i+) for ( j = 1; j vexnum; j+) printf(%d ,D-arcij.adj); printf(n); void sort(edge edges,MGraphA *D)/对权值进行排序 int i, j; for ( i = 1; i arcnum; i+) for ( j = i + 1;
28、j arcnum; j+) if (edgesi.weight edgesj.weight) Swapn(edges, i, j); 12 / 20 printf(-权排序之后的为:n); for (i = 1; i arcnum; i+) printf( %dn, edgesi.begin, edgesi.end, edgesi.weight); void Swapn(edge *edges,int i, int j)交换权值 以及头和尾 int temp; temp = edgesi.begin;edgesi.begin = edgesj.begin; edgesj.begin = tem
29、p; temp = edgesi.end; edgesi.end = edgesj.end; edgesj.end = temp; temp = edgesi.weight; edgesi.weight = edgesj.weight; edgesj.weight = temp; void MiniSpanTree(MGraphA *D)/ 生成最小生成树 (int i, j, n, m,SUM=0; int k = 1; int parentM; edge edgesM; for ( i = 1; i vexnum; i+) (for (j = i + 1; j vexnum; j+) (i
30、f (D-arcij.adj = 1)(edgesk.begin = i; edgesk.end = j; edgesk.weight = D-arcij.weight; k+; sort(edges, D); for (i = 1; i arcnum; i+) (parenti = 0; printf(最小生成树为:n); for (i = 1; i arcnum; i+)/ 核心部分 (n = Find(parent, edgesi.begin); m = Find(parent, edgesi.end); if (n != m) (parentn = m; printf( %dn, ed
31、gesi.begin, edgesi.end, edgesi.weight); SUM=SUM+edgesi.weight; cout最少生成树的代价:; cout 0) (f = parentf; return f; void main() (algraph gra; 13 / 20 MGraph G; MGraphA *D; int i,d,m,g2020; char a=a; int s; char y=y; while(y=y)( printf( - . 应小生成树的求法 . n); printf( _ _ n); printf( | 1.邻接矩阵(无向图) |n); printf(
32、| 2.用prim算求最小生成树(无向图) |n); printf( | 3.用kruskal算法求最小生成树 |n); printf( |_ _ |n) printf(- 肯选择相应的菜单(1-3) :); cins; switch(s) (case 1: d=creatMGraph(G); vnode v; coutendl注意:若该图为非强连通图(含有多个连通分量)时endl 最小生成树不存在,则显示为非法值endlendl; break; case 2: coutprim 算法求解如下:endl; for(i=0;i!=G.vexnum;+i) for(int j=0;j!=G .ve
33、xnum;+j)gi+1j+1=G .arcsij.adj; prim(g,d); break; case 3: coutkruskal 算法求解如下:endl; D = (MGraphA*)malloc(sizeof(MGraphA); CreatGraph(D); MiniSpanTree(D); break; printf(n); coutendly; if(y=n) break; 四、调试分析与体会 在我组的集体努力下,课程设计终于完成,由于我们对数据结构和 c语言不是很了解, 有时忽略了一些关键的细节,使得在编写程序的过程中出现了一些问题。对于打字有时粗 心导致14 / 20 出现一
34、些难以发现的小错误, 在我们的耐心,细致的调试下最终使得程序能够运行, 课程设计完满完工。 1、 问题一:求出图中的最小值 现象:求出的最小值是0 原因:图中没有连通的两个顶点之间的权值赋值为 0 2、 问题二:求最小生成树时,else句需再调用一个函数 现象:对某些二义树能求出最小生成树,但不能普遍适应 原因:对于找最小生成树边的各种可能没有考虑全面,代码才没有广泛的适应性 3、问题三:两个顶点之间的边是否是最小生成树的边 现象:代码的功能不能分辨出是否是最小生成树的边 原因:把简单的代码写的很复杂,从而杂乱无章出现错误 五、运行结果 将程序员录入后,让其运行。将会出现一个菜单的界面,执行各
35、种操作均有其对应的 代码。要执行何种操作只需输入对应的指令即可进行,在每步操作后均会有相应的提示。 操作简单方便实用,下面即为一些操作的示意图。 运行程序后出界面,运行结果如图1所示。 m “E:诙料二诙料二 专专业业谋程贪料、程序实践谋程贪料、程序实践Web哗诿哗诿: :是小生成树是小生成树.exk 最小生成树的求法 . d ! ! 建立建立邻援矩阵匚邻援矩阵匚无向图无向图 : ! 2 一用的一用的 0 0 箕注亲箕注亲最小段树最小段树无无向图向图 ! ! : 3 - kMiskal算法求最小生成树算法求最小生成树 : : : : 请选择相应请选择相应的菜单的菜单d-3X. . , 图1初界面 图中有1-3三个选项,可选取其中的一个选项进行操作 选取选项1进行操作,运行结果如图2所示 15 / 20 图2建立邻接矩阵 依据提示,分别输入无向图的顶点个数与弧的个数, 然后依次输入各个顶点所对应的 符号及与各个顶点相关联的弧与权值,存在邻接矩阵中。 若选取选项3,运行结果如图4所示。 方方 E:资料二资料二1专业课程资
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- (28)-考点28 补写句子
- (1)-专题01 写人作文(讲义)
- 《东方与西方文化差异》课件
- 《公务卡使用管理与操作指南》课件
- 网站商业计划书(样例)
- 初中地理湘教版八年级下册第一节 香港特别行政区的国际枢纽功能教学设计及反思
- 延安大学西安创新学院《财经英语》2023-2024学年第一学期期末试卷
- 武汉理工大学《藏医格宁学》2023-2024学年第一学期期末试卷
- 内蒙古丰州职业学院《中国对外经贸》2023-2024学年第二学期期末试卷
- 武汉工程科技学院《药物研究仪器操作及分析》2023-2024学年第一学期期末试卷
- 2025届江苏省南通市如皋市高三下学期适应性考试(二)物理考试(含答案)
- 人力资源管理行业的未来发展趋势
- 2025年许昌职业技术学院单招职业适应性考试题库及答案1套
- 环境突发事件应急预案演练记录
- 定期清洗消毒空调及通风设施制度
- 实战经验:2024年记者证考试试题及答案
- 无线电基础知识培训课件
- 投资咨询工程师项目后评价试题及答案
- 4.1 基因指导蛋白质的合成(课件)高一下学期生物人教版(2019)必修2
- 医疗器械质量管理体系制度
- 外研版(三起)(2024)三年级下册英语Unit 3 单元测试卷(含答案)
评论
0/150
提交评论