1、(1)利用克鲁斯卡尔算法求网的最小生成树。(2)实现并查集。以此表示构造生成树过程中的连通分量。(3)以文本形式输出生成树中各条边以及他们的权值。 3、实现提示通讯线路一旦建立,必然是双向的。因此,构造最小生成树的网一定是无向网。设图的顶点数不超过30个,并为简单起见,网中边的权值设成小于100的整数,可利用C语言提供的随机数函数产生。图的存储结构的选取应和所作操作向适应。为了便于选择权值最小的边,此题的存储结构既不选用邻接矩阵的数组表示法,也不选用邻接表,而是以存储边(带权)的数组即边集数组表示图。2、详细设计根据课设题目要求,拟将整体程序分为三大模块,分别是:图的存储结构,并查集的实现,克
2、鲁斯卡尔算法的实现。1、边集数组的类型定义:typedef struct int x, y; int w;edge;x表示起点,y表示终点,w为权值。2、并查集功能的实现由以下函数实现:Make_Set(int x)初始化集合;Find_Set(int x) 查找x元素所在的集合,回溯时压缩路径;Union(int x, int y, int w)合并x,y所在的集合。3、克鲁斯卡尔算法的实现该算法的实现位于主函数中: qsort(e, n, sizeof(edge), cmp); /将边排序 printf(最小生成树的各条边及权值为:n); for (i = 0; i n; i+) x =
3、Find_Set(ei.x); y = Find_Set(ei.y); if (x != y ) printf(%c - %c : %dn, ei.x + A, ei.y + , ei.w); Union(x, y, ei.w); 4、设计中还包含以下函数:(1)/* 比较函数,按权值(相同则按x坐标)非降序排序 */int cmp(const void *a, const void *b) if (*(edge *)a).w = (*(edge *)b).w) return (*(edge *)a).x - (*(edge *)b).x; return (*(edge *)a).w - (*
4、(edge *)b).w;(2)快排函数qsort,包含在stdlib.h头文件里(3)C语言提供的随机数函数srand( unsigned int seed );使用随机数函数如下:srand( (unsigned)time( NULL ) ); for( i = 0;i+ ) ei.w=rand()%100+1; ei.x = chx - ;if(chy=h+48) chx+; ei.y = (chy+) - if(chy=h+49) chy=chx+1; Make_Set(i);输出1100之间的随机数,使用rand()%100+1。5、主程序的流程图三、调试分析调试过程中遇到的问题:随
5、机产生权值时,通过边数不能确定起点和终点。解决:通过顶点数对所有边取随机数。四、用户使用说明及测试结果1、打开界面:(1)人为输入权值,输入1,回车:输入7,回车:输入边的信息及结果如下:(2)随机生成权值,输入0:输入顶点数5,结果如下:五、经验和体会通过本次课程设计,我学会了利用克鲁斯卡尔算法求最小生成树。另外学会了利用随机函数产生随机数,以及课本没有提到的边集数组的定义和使用。六、附录源代码#include stdlib.h#include time.h#define MAX 435/* 定义边(x,y),权为w */edge eMAX;/* rankx表示x的秩 */int rankM
6、AX;/* fatherx表示x的父节点 */int fatherMAX;/* 比较函数,按权值(相同则按x坐标)非降序排序 */* 初始化集合 */void Make_Set(int x) fatherx = x; rankx = 0;/* 查找x元素所在的集合,回溯时压缩路径 */int Find_Set(int x) while(fatherx) x=fatherx; return x;/* 合并x,y所在的集合 */void Union(int x, int y, int w) if (x = y) return; /* 将秩较小的树连接到秩较大的树后 */ if (rankx ran
7、ky) fathery = x; else if (rankx = ranky) ranky+; fatherx = y;/* 主函数 */int main() printf(*最小生成树问题: int i, n,h,k=0; char chx, chy;n人为输入权值请输入1,随机生成权值请输入0: scanf(%d,&k); if(k=1) /* 读取边的数目 */请输入边的条数(小于436): scanf(, &n); getchar(); /* 读取边信息并初始化集合 */请输入边的信息(起点,终点,权值(100)分别用空格隔开:%c %c %dchx, &chy, &ei.w); getchar(); ei.x = chx - ei.y = chy - else请输入顶点数(=30):h); srand( (unsigned)time( NULL ) ); n=(h-1)*h/2;chx=49;chy=50;随机生成的各条边及权值为: /* 将边排序 */ return 0;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1