数据结构(JAVA)课程设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
上海电力学院
数据结构(JA V A)
课程设计
题目: 最小生成树问题
学号:20083377
*名:***
院系:计算机与信息工程学院
专业年级:软件工程2008级
2011 年11 月23日
目录
一、设计目的: (2)
二、设计内容: (3)
1、问题描述: (3)
2、基本要求: (3)
3、试验提示: (3)
4、选做内容: (3)
三、概要设计: (3)
四、详细设计: (4)
1、构建所有城市顶点全连接: (4)
2、对数组edges[]中的值进行堆排序: (5)
Sort.sort(edges); (5)
3、用克鲁斯卡尔算法实现最小生成树: (6)
4、类的设计: (9)
五、程序代码: (14)
1、class Edge: (14)
2、class Sort: (15)
3、class MainTest: (16)
六、程序测试: (18)
七、课程设计心得: (22)
八、参考资料: (22)
一、设计目的:
(1)熟练掌握图的创建及遍历基本操作算法。
(2)熟练掌握图的最小生成树算法及应用。
(3)利用以存储边(带权)的数组表示图,实现在n个城市之间建设最低的经济代价的通信网络。
二、设计内容:
1、问题描述:
若要在n个城市之间建设通信网络,只需要架设n-1条线路即可。如何以最低的经济代价建设这个通信网,是一个网的最小生成树问题。
2、基本要求:
(1)利用克鲁斯卡尔算法求网的最小生成树。
(2)实现教科书中定义的抽象数据类型MFSet。以此表示构造生成树过程中的连通分量。
(3)以文本形式输出生成树中各条边以及他们的权值。
3、试验提示:
通信线路一旦建立,必然是双向的。因此,构造最小生成树的网一定是无向网。设图的顶点数不超过30个,并为简单起见,网中边的权值设成小于100的整数,可利用C语言提供的随机数函数产生。
图的存储结构的选取应和所作操作相适应。为了便于选择权值最小的边,此题的存储结构既不选用邻接矩阵的数组表示法,也不选用邻接表,而是以存储边(带权)的数组表示图。
4、选做内容:
利用堆排序(参见教科书)实现选择权值最小的边。
三、概要设计:
此次我们设计的这个在n个城市之间建设的通信网络,用最小生成树的方法,算出经济代价最小的网络。我们首先要把通信网络所有的带权值的边生成出来,即所有城市顶点间的全连接。接着,利用堆排序算法把所有的带权值的边,从小到大排列起来。然后,用克鲁斯卡尔算法,求出最小生成树。
类的设计:我们抽象出一个带权值边的类class Edge,它有三个属性(private int start, end, value;),即起点、终点和权值。在抽象出一个堆排序类class Sort。其余的都放到public class MainTest的main()函数里了。其实只为了简单点,所以类少了点,其实这个程序本身就很简单。
四、详细设计:
1、构建所有城市顶点全连接:
首先,我们随机生成15到30vertexNumber个顶点,生成[vertexNumber*(vertexNumber-1)/2]个全连接需要边edges[]。然后,这个问题需要所要城市之间的全连接,但是是无向的并且每个城市不可形成自环,所以要有vertexNumber-1个row和row-1个column。然后随机生
值为50到100的权值x。然后按顺序加入到Edge[] edges里。自此我们得到了所有顶点的全连接,并且记录了所有带权值的边edges。
代码:
int vertexNumber=(int)((Math.random()+1)*15);
System.out.println("随机生成"+vertexNumber+"个顶点");
Edge edges[]=new Edge[vertexNumber*(vertexNumber-1)/2];
for(int row=0, index=0; row for(int column=0; column int x=(int)((Math.random()+1)*50); edges[index] = new Edge(row, column, x); System.out.println("顶点"+row+"和"+column+"之间的距离为"+x); index++; } } 2、对数组edges[]中的值进行堆排序: 将所有带权值的边edges按权值从小到大的顺序排列,拆分成了三个函数实现。首先sort.sor(edges),然后sort中创建最大堆,然后把data[]数组中的data[0]和data[j]交换使得权值最大的edge放到了数组最后,然后j--,使得得到的权值最大的edges不用再堆排序,接着又得到了一个最大权值的edges的data[0]和data[j]交换则data数组的倒数第二个位置得到了数组中的倒数第二个大的值的edges。一直循环,得到了带权值边的edges按权值从小到大排列的数组。 具体代码如下,其实就是堆排序,就不详细说明了。 Sort.sort(edges); public static void sort(Edge data[]){ int length = data.length; //创建最大堆 for(int i = length/2-1; i>=0; i--){ sift(data, i, length-1); } //排序 for (int j = length - 1; j > 0; j--) { //交换data[0]和data[j] Edge e = data[0]; data[0] = data[j];