1、最小生成树的课程设计SHENYANG UNIVERSITY OF TECHNOLOGY数据结构与算法课程设计报告课程设计题目:构造可以使 n个城市连接的最小牛成树专业班级: 信息与计算科学1001班姓 名: 学 号:设计时间:2011-12-26批阅时间:指导教师:成绩:构造可以使n个城市连接的最小生成树主要任务:给定一个地区的n个城市间的距离网,用Prim算法或Kruskal算法建立最 小生成树,并计算得到的最小生成树的代价。设计该程序的基本要求:1、 城市间的距离网采用邻接矩阵表示,邻接矩阵的存储结构定义采用课本 中给出的定义,若两个城市之间不存在道路,则将相应边的权值设为自己定义 的无穷
2、大值。要求在屏幕上显示得到的最小生成树中包括了哪些城市间的道路, 并显示得到的最小生成树的代价。2、 表示城市间距离网的邻接矩阵(要求至少 6个城市,10条边)3、 最小生成树中包括的边及其权值,并显示得到的最小生成树的代价。总体设计1该程序的主要功能:能实现根据输入城市的信息可以判断该城市间的距离网是否构成最小生成树,遍历城市生成最小生成树,通过计算得到最小生成 树的代价。2该城市间的距离网用邻接矩阵表示3用克鲁斯卡尔(Kruskal )算法建立最小生成树详细设计说明1该程序的主要功能:能实现根据输入城市的信息可以判断出该城市间的距 离网是否构成最小生成树,遍历城市生成最小生成树,通过计算得
3、到最小生成树 的代价。该程序的模块结构功能图及主要函数如下:精品资料a)intmai n ()/主程序b)intmenu ()/菜单函数c)voidcreate ()输入城市信息函数d)voidjudge ()判断是否能够生成最小生成树函数e)voiddisplay()/打印输出f)voidset ()初始化pre,rank函数g)voidfind ()判断是否构成回路函数h)voidUn io n ()将能构成最小生成树的边添加到一个集合1)voidKrushal()/克鲁斯算法求最小生成树体会确定程序功能设计出总体流程对整个设计进行非常重要,明确要完成设计需要的 程序算法,为整个设计流程划
4、出大纲,可以使整个设计思路更加简单明了。2构造结构体本题为求最小生成树,先要构造一个结构体,再用邻接矩阵的形式表现出来。#defi ne max 20#defi ne MAXLNT 10typedef struct node /* 构造一个结构体,两个城市可以看成起点和终点,之间的道路可以看 成一个边*/int str; /* 起点 */int end; /* 终点 */int dis;/* 距离 */n ode;node pmax,temp; /*p 记录城市信息 */int pre100,ra nk100;/* 用于判断是否构成回路 */arcs记录城市间权值*/int n=O,arcsM
5、AX_LNTMAX_LNT;/* n 表示城市个数,3初始化void set(int x)/* 初始化 */prex = x;ran kx = 0;int find(int x)/*找到这个点的祖先*/if(x != prex)prex = fin d(prex);return prex;void Union (i nt x,int y)/* 将这两个添加到一个集合里去 */x = fin d(x);y = fin d(y);if(ra nkx = ran ky)prey = x;ran kx +;else prey = x;该城市间的距离网使用邻接矩阵表示,邻接矩阵存储方法(数组存储方法)
6、,利用两个数组来存储一个图。用a i j数组,利用邻接矩阵方式来储存城市与城市 间信息。void create( ) /*输入城市信息*/int i,j;printf(请输入城市的个数:n);scan f(%d, &n);printf(输入%d个城市的邻接矩阵:n,n);for(i = 1;i = n;i +)for(j = 1;j = n;j +)scan f(%d, &arcsij);3算法设计(1) 克鲁斯卡尔算法思想基本描述:假设连通图N=(V,E),则令最小生成树的初始状态为只有 n顶点而无 边的非连通图T=(V, ),图中每个顶点自成一个连通分量。在 E中选择代价最 小的边,若该边
7、依附的顶点落在 T中不同的连通分量上,则将此边加入到 T中, 否则舍去此边而选择下一条代价最小的边。以此类推,直至 T中所有顶点都在同一个连通分量上为止。(2) 克鲁斯卡尔算法设计a. 设置计数器E,初值为0,记录已选中的边数。将所有边从小到大排序,存于P中。b. 从p中选择一条权值最小的边,检查其加入到最小生成树中是否会构成回路,若是,则此边不加入生成树;否则,加入到生成树中,计数器 E累加1c. 从E中删除此最小边,转d. 判断是否构成回路的方法:void Kruskal( )int ans = O,i,j,k = 0;int in dex;int count = 0;for(i = 1;
8、i = n;i +)set(i);for(i = 1;i = n;i +)for(j = i + 1;j = n;j +)p+k.str = i; pk.e nd = j;pk.dis = arcsij; /*b继续执行,直到k=n-1,算法结束/*ans用来记录生成最小树的权总值 */*记录打印边的条数*/* 初始化数组 prex,rankx*/先把所有城市之间的路段看成一个边 */for(i=1;i=k;i+) /*把所有的边按从小到大进行排序 */in dex=i;for(j=i+1;j=k;j+) if(pj.dis pi ndex.dis) in dex=j;temp=pi ndex
9、;pi ndex=pi;pi=temp;for(i = 1;i = k;i +)if(fin d(pi.str) != fin d(pi.e nd)/* 如果这两点连接在一起不构成一个回路, 则执行下面操作*/printf(t 第 %d 条路段为:d-%d,权值为 %dn,+coun t,pi.str,pi.e nd,pi.dis);/* 将这条边的起点、终点打印出来 */ans += pi.dis; /*说明这条路段要用*/Union( pi.str,pi.e nd);printf(t遍历所有城市得到最小生成树的代价为 :%dnn,ans);设置集合S,其中存放已加入到生成树中的边所连接的顶
10、点集合,当一条新的边要加入到生成树中时,检查此边所连接的两个顶点是否都已经在 S中,若是则表示构成回路,否则,若有一个顶点不在 S中 或者两个顶点都不在S中,则不够成回路。void judge( )/*判断是否能够生成最小生成树 */int close100,low100,i,j,ans = 0;/*closej 表示离 j 最近的顶点,lowj表示离 j 最短的距离*/int use100;use1 = 1;for(i = 2;i = n;i +)lowi = arcs1i; /* 初始化 */closei = 1;usei = 0;for(i = 1;i n;i +)int min = 1
11、00000000,k = 0;for(j = 2;j lowj)/* 找到最小的low值,并记录*/min = lowj;k = j;for(j = 2;j arcskj)lowj = arcskj; /* 修改 low值和 close值 */closej = k;ans += arcsclosekk;if(ans = 100000000) printf(不能构成最小生成树 n);elseprintf(”能构成最小生成树n);克鲁斯卡尔算法 (Kruskals algorithm)是两个经典的最小生成树算法的较为简单理解的一个。这里面充分体现了贪心算法的精髓。克鲁斯卡尔算法生成最小生成树的过程
12、(3 )防止不能构成最小生成树的图为避免输入的图构成的不是连通图,设计了 judge ()函数来判断输入数据 构成的是否为连通图,此函数的主要算法是源于普里姆( PRIM )算法,经过改 编,形成了新的函数。4主函数的设计int main( ) /*主函数 */while(1)switch( menu( )case 1:create( );break;/* 输入城市信息 */case 2:judge( );break;/* 判断是否能够生成最小生成树 */case 3:display( );break; /*显示生成的最小生成树 */case 4:exit( 0 );return 0;调试与测
13、试网络图GE162019odA16O011CO652011od2214QO19cd22018oOod61418od9V509y邻接矩阵生成界面 20111229 3 求最小生成树43权S i 自st取 信一成 ES市 之 leKn有 替帰 U 12 3 4请输入所选功百別-4输入城市间信息20111229 0求最小生成树S4枫I艺成T生亲信一成间构帀1市否有入断历岀WWS12 3 4请输人所选功冃也-4詁输入城市的个数= 20111229 0 求最小生成树请输入所选功月也Y请输入城市的个数醫為入石个城市的邻接矩阵:主成 尘 意个最 信一成 SH 间构市 之市否有 入断历岀 H 12 3 4I月输入所选功能4器输入城市的个数: 爲入石个城市的邻接矩阵:10006 16 28 9 10030 1000016 10000 11 1000
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1