数据结构课程设计java最小生成树.docx
- 文档编号:3944149
- 上传时间:2022-11-26
- 格式:DOCX
- 页数:19
- 大小:132.16KB
数据结构课程设计java最小生成树.docx
《数据结构课程设计java最小生成树.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计java最小生成树.docx(19页珍藏版)》请在冰豆网上搜索。
数据结构课程设计java最小生成树
上海电力学院
数据结构(JAVA)课程设计
题目:
____最小生成树_______
学生姓名:
_****___________
学号:
_____*******_______
院系:
计算机科学与技术学院
专业年级:
______*****___级
20**年*月**日
目录
1.设计题目................................................1
2.需求分析................................................1
1)运行环境................................................1
2)输入的形式和输入值的范围................................1
3)输出的形式描述..........................................1
4)功能描述................................................1
5)测试数据...............................................1
3.概要设计................................................1
1)抽象数据类型定义描述...................................1
.2)功能模块设计..........................................1
3)模块层次调用关系图......................................2
4.详细设计。
实现概要设计中定义的所有的类的定义及类中成员函数,并对主要的模块写出伪码算法。
...........................2
5.调试分析。
包括调试过程中遇到的问题及解决的方法、算法的时间空间复杂性分析、经验体会。
.................................6
6.用户使用说明。
详细列出每一步的操作说明。
.................7
7.测试结果...............................................7
8.附录:
程序设计源代码.....................................9
一、设计题目
1).问题描述
若要在n个城市之间建设通信网络,只需要架设n-1条线路即可。
如何以最低的经济代价建设这个通信网,是一个网的最小生成树问题。
2).基本要求
以邻接多重表存储无向带权图,利用克鲁斯卡尔算法或普瑞姆算法求网的最小生成树。
二、需求分析
1)运行环境
软件在JDK运行,硬件支持windows系统
2)输入的形式和输入值的范围
自动生成顶点数据在10~20之间;各个顶点之间权值在25~50之间;通过程序改动亦可生成已知顶点权值之间的最小生成树,需将随机生成代码改为
edgeedge[]={newedge(0,1,16),new(0,2,18)......};
将已知顶点、权值通过其函数输入再生成其所对应最小生成树。
3)输出的形式描述
输出随机生成顶点个数以及各个顶点之间权值;然后输出本次生成顶点之间构成的最小生成树。
4)功能描述
该程序会自动生成介于10~20个数顶点模拟各城市,再随机生成介于25~50之间数值作为权值模拟各个城市间的距离,并同时生成此次顶点、权值相对应的最小生成树,模拟各城市间的最小距离,最小生成树。
如有确定城市顶点及其权值,则可改动程序令其不再随机生成顶点权值,在程序中输入如下代码:
edgeedge[]={newedge(0,1,16),new(0,2,18)......}
输入数组为edge数组,edge(起点,终点,权值)。
通过将随机生成代码改动就可以生成该城市对应权值的最小生成树。
5)测试数据
生成数据之后检验生成顶点数值是否介于10~20之间;检验各顶点间权值大小是否介于25~50间;同时检验其自动生成最小生成树是否正确。
三、概要设计
1)抽象数据类型定义描述
定义排序类sort,将各个顶点按照其两顶点之间权值大小排序,从大到小排序,用到堆排序算法;
定义带权值的边edge,分别存在start(起点)、end(终点)、value(权值)三个变量;
定义main类,调用sort、edge类与自身函数通过Kruskal函数实现最小生成树。
2)功能模块设计
主函数随机生成10~20个顶点作为城市并同时生成任意两顶点间25~50的权值作为两城市距离;在界面输出随机生成顶点个数及任意两顶点间权值;再调用sort函数对权进行排序,按照权值的大小有小到大排序;排序之后实现Kruskal函数,通过kruskal函数生成最小生成树;最后输出所生成的最小生成树。
3)模块层次调用关系图
四、详细设计
实现概要设计中定义的所有的类的定义及类中成员函数,并对主要的模块
写出伪码算法。
1.定义带权值的边及其三个变量start(起点)、end(终点)、value(权值);定义该属性为下边的根据权值排序、Kruskal实现最小生成树做下铺垫;函数实现如下:
packagetree;
publicclasssort{
publicstaticvoidsift(edgea[],introot,intlimit)
{
inti=root;
intj=i*2+1;//j为i的左孩子
while(j<=limit)//沿较小值孩子节点向下筛选
{
if(j { j++;//j为左右孩子的较小者 } if(a[j].getValue()>a[i].getValue())//若父亲节点值较大 { edgee=a[i];//孩子节点中较小值上移 a[i]=a[j]; a[j]=e; i=j; j=i*2+1;//i、j向下一层 } else{ break;//跳出循环 } } } publicstaticvoidsort(edgedata[]) { intlength=data.length; for(inti=length/2-1;i>=0;i--)//创建最大堆 { sift(data,i,length-1); } for(intj=length-1;j>0;j--)//每趟把最大值交换到后面字,再生成堆 { edgee=data[0]; data[0]=data[j]; data[j]=e; sift(data,0,j-1); } } } 2.随机生成介于10~20之间个顶点作为各个城市,并同时生成任意两顶点间权值,介于25~50之间;每n个顶点之间最多生成n*(n-1)条边;生成vertexNumber-1个row(行)和row-1个column(列)可以防止同一个顶点生成自环; 函数实现如下: intvertexNumber=(int)((Math.random()+1)*10); System.out.println("随机生成"+vertexNumber+"个顶点"); edgeedges[]=newedge[vertexNumber*(vertexNumber-1)/2]; for(introw=0,index=0;row {//row行、column列、index数组 for(intcolumn=0;column { intx=(int)((Math.random()+1)*25);//random随机的 edges[index]=newedge(row,column,x); System.out.println("顶点"+row+"和"+column+"之间的距离为"+x); index++; } } 3.定义排序类sort,按照堆排序函数对数组edge[]按照权值大小从小到大进行排序(参照课本299页); packagetree; publicclasssort{ publicstaticvoidsift(edgea[],introot,intlimit) { inti=root; intj=i*2+1;//j为i的左孩子 while(j<=limit)//沿较小值孩子节点向下筛选 { if(j { j++;//j为左右孩子的较小者 } if(a[j].getValue()>a[i].getValue())//若父亲节点值较大 { edgee=a[i];//孩子节点中较小值上移 a[i]=a[j]; a[j]=e; i=j; j=i*2+1;//i、j向下一层 } else{ break;//跳出循环 } } } publicstaticvoidsort(edgedata[]) { intlength=data.length; for(inti=length/2-1;i>=0;i--)//创建最大堆 { sift(data,i,length-1); } for(intj=length-1;j>0;j--)//每趟把最大值交换到后面字,再生成堆 { edgee=data[0]; data[0]=data[j]; data[j]=e; sift(data,0,j-1); } } } 4.Kruskal方法实现最小生成树。 Kruskal方法与Prim方法都是基于最小生成树的MST性质: 设G(V,E)是一个联通带权无向图,TV是顶点集合V的一个非空真子集。 若(tv,v)包含于E是一条权值最小的边,其中tv包含于TV,v包含于V-TV,则必定存在G的一棵最小生成树T,T包含边(tv,v)。 其Kruskal算法参照课本334页。 其算法如下: inta[]=newint[vertexNumber]; //初始时刻,所有顶点的连通分量编号为-1,表示所有顶点都属于一个独立的连通分量 for(inti=0;i { a[i]=-1; } edgeresult[]=newedge[vertexNumber-1]; //该数组用于记录最小生成树 inttemp=0; for(edgee: edges){ intstart=e.getStart(); intend=e.getEnd(); if(a[start]==a[end]&&a[end]==-1){ a[start]=a[end]=temp; result[temp]=e; temp++; } elseif(a[start]! =a[end]){ if(a[start]==-1){ a[start]=a[end]; } elseif(a[end]==-1){ a[end]=a[start]; } else{ intt=a[start]; for(inti=0;i if(a[i]==t){ a[i]=a[end]; } } } result[temp]=e; temp++; } 五、调试分析 包括调试过程中遇到的问题及解决的方法、算法的时间空间复杂性分析、 经验体会。 Sort排序类算法时间复杂度为O(log2n),Kruskal算法时间复杂度为O (1); 调试过程中,Kruskal算法实现出现问题,刚开始无法实现该函数,无法生成最小生成树;经请教同学、查看资料、查看课本解决问题。 实现堆排序过程无法实现,参考课本之后解得堆排序算法实现过程: 调用sift()方法n/2次,使得数据序列成为最大堆;对j=n-1,n-2...1,执行下列n-1次完成排序操作: 交换根end[0]和元素end[j],调用sift()方法将end[j]的前j个元素调整成最大堆。 在编程过程中如遇难题可对其题目进行认真分析,然后参考课本或者其他资料已现有代码亦或闻询他人帮助,在自己查询或者问询他人过程中也是自己学习的过程,可以从中学习到很多知识。 6、用户使用说明 程序运行后会自动跳出10~20个随机顶点作为各个城市,同时随机生成25~50的权值x,并生成此次所有顶点及其权值构成的最小生成树。 7、测试结果 1.生成0-12共13个顶点: 2.生成最小生成树为: 程序随机自动生成介于10~20之间个顶点正确运行,随机自动生成介于25~50之间权值正确运行,使得任意两顶点之间权值于25~50之间;经验证该生成树为最小生成树,程序运行正确。 最小生成树定义: 设G是一个带权连通无向图,w(e)是边e上的权,T是G的生成树,T中各边的权值之和称为生成树T的权值或者代价(cost)。 权值最小的生成树称之为最小生成树(minimumcostspanningtree),简称最小生成树。 八、附录: 程序设计源代码 packagetree; publicclasssort{ publicstaticvoidsift(edgea[],introot,intlimit) { inti=root; intj=i*2+1;//j为i的左孩子 while(j<=limit)//沿较小值孩子节点向下筛选 { if(j { j++;//j为左右孩子的较小者 } if(a[j].getValue()>a[i].getValue())//若父亲节点值较大 { edgee=a[i];//孩子节点中较小值上移 a[i]=a[j]; a[j]=e; i=j; j=i*2+1;//i、j向下一层 } else{ break;//跳出循环 } } } publicstaticvoidsort(edgedata[]){ intlength=data.length; for(inti=length/2-1;i>=0;i--)//创建最大堆 { sift(data,i,length-1); } for(intj=length-1;j>0;j--)//每趟把最大值交换到后面字,再生成堆 { edgee=data[0]; data[0]=data[j]; data[j]=e; sift(data,0,j-1); } } } packagetree; publicclassedge{ privateintstart,end,value;//定义开始、结束、权值 publicedge(intstart,intend,intvalue){ this.start=start; this.end=end; this.value=value; } publicintgetStart(){ returnstart; } publicvoidsetStart(intstart){ this.start=start; } publicintgetEnd(){ returnend; } publicvoidsetEnd(intend){ this.end=end; } publicintgetValue(){ returnvalue; } publicvoidsetValue(intvalue){ this.value=value; } } packagetree; publicclassmain { publicstaticvoidmain(Stringargs[]) { intvertexNumber=(int)((Math.random()+1)*10); System.out.println("随机生成"+vertexNumber+"个顶点"); edgeedges[]=newedge[vertexNumber*(vertexNumber-1)/2]; for(introw=0,index=0;row {//row行、column列、index数组 for(intcolumn=0;column { intx=(int)((Math.random()+1)*25);//random随机的 edges[index]=newedge(row,column,x); System.out.println("顶点"+row+"和"+column+"之间的距离为"+x); index++; } } sort.sort(edges);//对数组edges[]中的值进行堆排序 inta[]=newint[vertexNumber]; for(inti=0;i //初始时刻,所有顶点的连通分量编号为-1,表示所有顶点都属于一个独立的连通分量 { a[i]=-1;//a[i]的值表示第i个顶点所属的连通分量编号 } //该数组用于记录最小生成树 edgeresult[]=newedge[vertexNumber-1]; inttemp=0; for(edgee: edges){ intstart=e.getStart(); intend=e.getEnd(); if(a[start]==a[end]&&a[end]==-1)//只要将要加入result[]的edges的两个顶点相等都为-1, //说明不和result[]中的已经加入的联通分量有关系,则可以直接加入result[]。 { a[start]=a[end]=temp; result[temp]=e; temp++; } elseif(a[start]! =a[end]) { if(a[start]==-1) //start=-1为悬空顶点,那么就让start=end,使加入的连通分量和其连接的result[]中连通分量的标识统一。 { a[start]=a[end]; } elseif(a[end]==-1) //end=-1为悬空顶点,那么就让end=start,使加入的连通分量和其连接的result[]中连通分量的标识统一。 { a[end]=a[start]; } else{ intt=a[start]; for(inti=0;i //要加入的edges使得result中的两个不同的连通分量连接起来,需将一个和另外一个进行统一 //遍历所有的顶点如果值和start相等就都等于end,则两个连通分量进行了统一 { if(a[i]==t) { a[i]=a[end]; } } } result[temp]=e;//得到了result[] temp++; } //System.out.println("------------"); //System.out.println(Arrays.toString(a)); if(temp==vertexNumber-1) { break; } } System.out.println("最小生成树为: "); for(edgee: result) { System.out.println("连接顶点"+e.getStart()+"和"+e.getEnd()+"该边的权值为"+e.getValue()); } } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 java 最小 生成