最小生成树普利姆算法的实现.docx
- 文档编号:4113700
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:22
- 大小:166.97KB
最小生成树普利姆算法的实现.docx
《最小生成树普利姆算法的实现.docx》由会员分享,可在线阅读,更多相关《最小生成树普利姆算法的实现.docx(22页珍藏版)》请在冰豆网上搜索。
最小生成树普利姆算法的实现
数据结构课程设计
设计说明书
最小生成树普利姆算法的实现
学生姓名
学号
班级
成绩
指导教师
数学与计算机科学学院
年月日
数据结构课程设计评阅书
题目
最小生成树普里姆算法的实现
学生姓名
学号
指导教师评语及成绩
指导教师签名:
年月日
答辩评语及成绩
答辩教师签名:
年月日
教研室意见
总成绩:
室主任签名:
年月日
课程设计任务书
2011—2012学年第二学期
专业:
学号:
姓名:
课程设计名称:
数据结构课程设计
设计题目:
最小生成树普利姆算法的实现
完成期限:
自年月日至年月日共周
设计依据、要求及主要内容:
在图论中,常常将树定义为一个无回路连通图。
对于一个带权的无向连通图,其每个生成树所有边上的权值之和可能不同,我们把所有边上权值之和最小的生成树称为图的最小生成树。
求图的最小生成树有很多实际应用。
例如,通讯线路铺设造价最优问题就是一个最小生成树问题。
普里姆算法的基本思想:
从连通网络N={V,E}中的某一顶点u0出发,选择与它关联的具有最小权值的边(u0,v),将其顶点加入到生成树的顶点集合U中。
以后每一步从一个顶点在U中,而另一个顶点不在U中的各条边中选择权值最小的边(u,v),把该边加入到生成树的边集TE中,把它的顶点加入到集合U中。
如此重复执行,直到网络中的所有顶点都加入到生成树顶点集合U中为止。
假设G=(V,E)是一个具有n个顶点的带权无向连通图,T(U,TE)是G的最小生成树,其中U是T的顶点集,TE是T的边集,则构造G的最小生成树T的步骤如下:
1)初始状态,TE为空,U={v0},v0∈V;
2)在所有u∈U,v∈V-U的边(u,v)∈E中找一条代价最小的边(u′,v′)并入TE,同时将v′并入U;
重复执行步骤
(2)n-1次,直到U=V为止。
要求:
(1)任意给出一个带权值的连通网络图,能够遍历图中的所有节点。
(2)根据普里姆的算法思想,输出针对这个连通网络图的最小生成树。
(3)界面友好,可操作性强。
指导教师(签字):
教研室主任(签字):
批准日期:
年月日
摘要
针对现实生活中,许多地方需要考虑到如:
邮递员送信,在n个城市之间建立通信网络等最短路径的问题,本应用程序正是基于这一现实问题,在vc++的平台下,采用普里姆算法对此作出解决,本程序主要包含2大模块,分别为采用邻接矩阵的存储方式建立带权的无向网络图和利用普里姆算法对所建的网络图求最小代价生成树。
它的最终目的是以最经济、最实惠、最节约的方式解决生活中的最短路径问题,以求给人们提供更节约、更便利的生活。
关键词:
最短路径;普里姆算法;最小生成树;经济节约
1.课题的描述
在我们的平时生活中,人们都希望花最少的时间或者最少的金钱将一件事情办成,例如:
一个邮递员想走最短的路把手中的物件送到收件人手中,通信公司想花费最少的金钱把通信网络覆盖在n个城市之间,这些都可归纳为求最短路径问题。
本课题利用普里姆算法来实现譬如通信网络中各种连接方式中的最短路径问题,从而达到一条最优线路,以使金钱或时间的花费最小,达到解决成本的目的。
开发工具:
visualc++6.0
2.设计过程
本设计是基于最小生成树普里姆算法的思想上,以实现在网络中可以选择出最短线路,从而达到省时省力的效果。
2.1问题的分析与任务的制定
假设要在n个城市之间建立通信联络网,则联通n个城市只需要n-1条线路,然而n个城市之间最多可能设置n(n-1)/2条线路,此时,自然会考虑一个问题,如何在这些可能的线路中选择n-1条,使的在最节省经费的前提下建立起这个通信网。
这就可以简化为构造联通网的最小代价生成树(简称最小生成树)问题。
任务:
根据普里姆的算法思想,输出连通网络图的最小生成树。
2.2需要解决的问题
(1)选择哪种存储结构建立一个带权的网络图;
(2)如何实现普里姆算法的功能;
(3)如何输出最小生成树;
2.3设计本程序的主要思想
普里姆算法的基本思想:
假设N={V,{E}}是一个联通网,TE是N上最小生成树中边的集合。
算法从U={u0}(u0∈V),TE={}开始,重复执行下属操作:
在所有的u∈U,v∈V-U的边(u,v)∈E中找一条代价最小的边(u0,v0)并入集合TE,同时v0并入U,知道U=V为止。
此时TE中必有n-1条边,则T=(V{TE})为N的最小生成树。
2.4分模块分析
(1)预处理部分
#include
#include
#include
#include
#defineMAX20
#defineMAX_NAME3
#defineINFINITYINT_MAX
(2)建立无向图
功能:
要寻找最小代价生成树,选择了用邻接矩阵建立的带权无向图。
实现过程:
在其函数体中,首先通过键盘输入无向图中的顶点数和边数,然后通过二重for循环初始化邻接矩阵,调用函数Locate()求出每条边所对应的两个顶点在顶点向量表中的位置后,将对应在邻接矩阵中的相应位置赋予权值,从而在邻接矩阵中存放了相关连的顶点之间边的权值,完成无向网的建立。
代码如下:
intCreateDN(MGraph&G)//采用数组(邻接矩阵)表示法,构造无向图G。
{
inti,j,k,w;
VertexTypeva,vb;
printf("\t\t请输入无向图的顶点数和边数:
");
scanf("%d%d",&G.vexnum,&G.arcnum);
if(G.vexnum<=1)
{
printf("\t\t最小生成树不存在!
");
return0;
}
printf("\t\t请依次输入%d个顶点:
",G.vexnum);
for(i=0;i scanf("%s",G.vexs[i]); for(i=0;i for(j=0;j { G.arcs[i][j].adj=INFINITY;//网初始化为无穷大 G.arcs[i][j].info=NULL; } printf("\t\t请依次输入一条边所依附的顶点及权值: \n",G.arcnum); for(k=0;k { scanf("%s%s%d%*c",va,vb,&w); i=LocateVex(G,va); j=LocateVex(G,vb); G.arcs[i][j].adj=G.arcs[j][i].adj=w; } printf("\t\t无向图建立成功! "); return1; } (3)无向图邻接矩阵的输出 功能: 输出所创建的无向图的邻接矩阵。 实现过程: 在本模块中通过对for循环的使用及打印语句的控制实现了邻接矩阵的输出功能。 代码如下: voidDisplay(MGraphG)//输出邻接 { inti,j; for(i=0;i { printf("\t\t"); for(j=0;j if(G.arcs[i][j].adj==INFINITY) { printf("\t∞"); } else {printf("\t%d",G.arcs[i][j]);} printf("\n"); } } (4)普里姆算法 功能: 是利用普里姆算法求出无向网所对应的最小生成树. 实现过程: 在其函数体中,首先,定义closedge用于存放最小生成树中的顶点,调用函数Locate()求出起点u在顶点向量表中的位置,初始化U={u},利用for循环对V-U中的顶点i,初始化,再利用for循环找n-1条边,其中,调用函数Minium()求出辅助数组中权值最小的边,并将其在辅助数组中的相应位置返回到主调函数中,最后,输出<起点->终点权值>。 代码如下: voidPRIM(MGraph&G,VertexTypeu) { inti,j,k; minsideclosedge; k=LocateVex(G,u); for(j=0;j { if(j! =k) { strcpy(closedge[j].adjvex,u); closedge[j].lowcost=G.arcs[k][j].adj; } } closedge[k].lowcost=0;//初始,U={u} printf("\t\t最小代价生成树的各条边及权值为: \n"); printf("\n"); printf("\t\t<起点->终点>\t权值\n"); for(i=1;i {//选择其余G.vexnum-1个顶点 k=minimum(closedge,G);//求出T的下一个结点: 第K顶点 printf("<%s-%s>\t\t%d\n",closedge[k].adjvex,G.vexs[k],closedge[k].lowcost);//输出生成树的边 closedge[k].lowcost=0;//第K顶点并入U集 for(j=0;j if(G.arcs[k][j].adj { //新顶点并入U集后重新选择最小边 strcpy(closedge[j].adjvex,G.vexs[k]); closedge[j].lowcost=G.arcs[k][j].adj; } } } (5)子函数intLocateVex(MGraphG,VertexTypeu) 功能: 是求出某个顶点在顶点向量表中的位置。 实现过程: 在其函数体中通过for循环将某一顶点与顶点向量表中的所有顶点进行比较,当出现两者相等时,将该顶点在vexs[]数组的下标通过return语句返回,否则返回-1; 代码如下: intLocateVex(MGraphG,VertexTypeu)//若G中存在顶点u,则返回该顶点在图中的位置,否则返回-1 { inti; for(i=0;i if(strcmp(u,G.vexs[i])==0) returni; return-1; } (6)子函数intminimum(minsideS,MGraphG) 功能: 是求出辅助数组中权值最小的边。 代码如下: intminimum(minsideS,MGraphG)//求closedge.lowcost的最小值 { inti=0,j,k,min; while(! S[i].lowcost) i++; min=S[i].lowcost;//第一个不为0的值 k=i; for(j=i+1;j if(S[j].lowcost>0) if(min>S[j].lowcost) { min=S[j].lowcost; k=j; } returnk; } (7)主函数voidmain() 功能: 完成对子函数的调用。 代码如下: voidmain() { MGraphG; for(;;) { switch(menu())//选择判断 { case1: printf("\t\t\t**建立无向图**\n"); printf("\n"); CreateDN(G); printf("\n"); system("pause"); break; case2: printf("\t\t\t**邻接矩阵的输出**\n"); printf("\n"); Display(G); printf("\n"); system("pause"); break; case3: printf("\t\t请输入从第几个顶点开始: "); scanf("%d",&u); PRIM(G,G.vexs[u-1]); system("pause"); break; case4: printf("\t\t谢谢您的使用! \n"); printf("\n"); system("pause"); exit(0); } } } 2.5流程图 通过上述分模块的概要设计,各程序模块之间的层次(调用)关系,流程图如下: 图2.1各函数之间的调用图 3.程序测试与分析 (1)第一组: 在创建的无向网中仅含有一个顶点,测试结果如下: 图3.1建立图 结果分析: 由于顶点数为1,不符合网的定义,所以不存在最小生成树。 (2)第二组: 输入2个顶点,一条边,测试结果如下: 图3.2建立无向图 图3.3邻接矩阵的输出 图3.4最小代价生成树 结果分析: 由于本次只输入了2个顶点,1条边,所以最短路径为仅有的一条边,权值为1. (3)第三组: 本次测试以课本p174中构造最小代价生成树为列,输入6个顶点,10条边,测试数据如下: 图3.5建立无向图 图3.6邻接矩阵的输出 图3.7最小代价生成树的输出 图3.8退出程序 结果分析: 本次测试在菜单选择中进行了错误测试,接着在建图时输入了6个顶点,10条边,在生成最小生成树时,以第一个顶点为起始顶点,最终得到了正确的结果。 总结 本次课程设计我主要是应用了数据结构和C语言里的一些知识,综合起来完成了本次课设,虽然程序很小,但却付出了很多。 本次课设的任务是完成最小生成树普里姆算法的实现,通过这次课程设计,首先让我体会到了该算法的实用性和简便性,也对该算法有了一个全新的认识和理解,让我把以前学习的知识得到巩固和进一步的认识;再次,在程序的编写过程中,也遇到了许多的问题,我们通过小组成员的讨论,问题最终得到了解决,让我意识到团队合作的重要性。 除此之外,通过这次课程设计,我发现了自己在编程方面还有很多的不足之处,加上现代社会科技发展的日新月异,计算机行业信息的更新程度之快,让我意识到我们更应该严格要求自己,时刻提醒自己提高自己的专业水平和自身的综合素质,只有这样,才不会被这个日新月异,迅速发展的社会所淘汰,才能够在未来找到自己的一块栖息地。 致谢 本次课程设计是我大学以来的第一次课程设计,因此在课程设计的过程中,遇到了许多问题,在这个过程中xx老师给了我和我们小组成员很大的帮助,在xx老师的耐心指导下,本次课设最终得以顺利完成。 在此,我代表我们小组成员对xx老师表示感谢,感谢xx老师在这2周对我们的指导与帮助。 参考文献 [1].谭浩强,C语言程序设计教程(第三版),高等教育出版社,2005年7月。 [2].严蔚敏,吴伟明。 数据结构(c语言版),清华大学出版社,2011年5月。 [3].耿国华,数据结构,c语言描述,西安电子科技大学出版社,2004年9月。 [4].徐孝凯,数据结构实用教程,清华大学出版社,2005年7月。 [5]. [6]. 附录 //程序目的: 最小生成树普里姆算法的实现 #include #include #include #include #defineMAX20//最大顶点个数 #defineMAX_NAME3//顶点字符串的最大长度+1 #defineINFINITYINT_MAX//用最大值∞ typedefintVRType; typedefcharInfoType; typedefcharVertexType[MAX_NAME]; typedefstruct { VRTypeadj;//顶点关系类型 //带权图,则为权值类型 InfoType*info;//该弧相关信息的指针(可无) }ArcCell,AdjMatrix[MAX][MAX]; typedefstruct//图的数据结构 { VertexTypevexs[MAX];//顶点向量 AdjMatrixarcs;//邻接矩阵 intvexnum,//图的当前顶点数 arcnum;//图的当前弧数 }MGraph; typedefstruct//记录从顶点集U到V-U的代价最小的边的辅助数组定义 { VertexTypeadjvex; VRTypelowcost; }minside[MAX]; intmenu() { intnumber; do { system("cls"); printf("\t\t*************数据结构课程设计***********\n"); printf("\t\t\t**1.建立无向图**\n"); printf("\t\t\t**2.邻接矩阵的输出**\n"); printf("\t\t\t**3.生成最小生成树**\n"); printf("\t\t\t**4.退出**\n"); printf("\t\t*****************************************\n"); printf("\t\t请选择(1-4): "); scanf("%d",&number); if(number>4||number<1) { printf("\t\t\t输入错误! 请重新输入: "); scanf("%d",&number); } }while(number>4||number<1); return(number); } intLocateVex(MGraphG,VertexTypeu) //若G中存在顶点u,则返回该顶点在图中的位置,否则返回-1 { inti; for(i=0;i if(strcmp(u,G.vexs[i])==0) returni; return-1; } intCreateDN(MGraph&G)//采用数组(邻接矩阵)表示法,构造无向图G { inti,j,k,w; VertexTypeva,vb; printf("\t\t请输入无向图的顶点数和边数: "); scanf("%d%d",&G.vexnum,&G.arcnum); if(G.vexnum<=1) {printf("\t\t最小生成树不存在! "); return0; } printf("\t\t请依次输入%d个顶点: ",G.vexnum); for(i=0;i scanf("%s",G.vexs[i]); for(i=0;i for(j=0;j { G.arcs[i][j].adj=INFINITY;//网初始化为无穷大 G.arcs[i][j].info=NULL; } printf("\t\t请依次输入一条边所依附的顶点及权值: \n",G.arcnum); for(k=0;k { scanf("%s%s%d%*c",va,vb,&w); i=LocateVex(G,va); j=LocateVex(G,vb); G.arcs[i][j].adj=G.arcs[j][i].adj=w; } printf("\t\t无向图建立成功! "); return1; } voidDisplay(MGraphG)//输出邻接矩阵 { inti,j; for(i=0;i { printf("\t\t"); for(j=0;j if(G.arcs[i][j].adj==INFINITY) { printf("\t∞"); } else { printf("\t%d",G.arcs[i][j]); } printf("\n"); } } intminimum(minsideS,MGraphG)//求closedge.lowcost的最小值 { inti=0,j,k,min; while(! S[i].lowcost) i++; min=S[i].lowcost;//第一个不为0的值 k=i; for(j=i+1;j if(S[j].lowcost>0) if(min>S[j].lowcost) { min=S[j].lowcost; k=j; } returnk; } voidPRIM(MGraph&G,VertexTypeu) //用普里姆算法从第u个顶点出发构造网G的最小生成树T,输出T的各条边 { inti,j,k; minsideclosedge; k=LocateVex(G,u
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 最小 生成 树普利姆 算法 实现