数据结构课程设计报告最小生成树Word文档下载推荐.docx
《数据结构课程设计报告最小生成树Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计报告最小生成树Word文档下载推荐.docx(12页珍藏版)》请在冰豆网上搜索。
(1)利用克鲁斯卡尔算法求网的最小生成树。
(2)实现并查集。
以此表示构造生成树过程中的连通分量。
(3)以文本形式输出生成树中各条边以及他们的权值。
3、实现提示
通讯线路一旦建立,必然是双向的。
因此,构造最小生成树的网一定是无向网。
设图的顶点数不超过30个,并为简单起见,网中边的权值设成小于100的整数,可利用C语言提供的随机数函数产生。
图的存储结构的选取应和所作操作向适应。
为了便于选择权值最小的边,此题的存储结构既不选用邻接矩阵的数组表示法,也不选用邻接表,而是以存储边(带权)的数组即边集数组表示图。
2、详细设计
根据课设题目要求,拟将整体程序分为三大模块,分别是:
图的存储结构,并查集的实现,克鲁斯卡尔算法的实现。
1、边集数组的类型定义:
typedefstruct
{
intx,y;
intw;
}edge;
x表示起点,y表示终点,w为权值。
2、并查集功能的实现由以下函数实现:
Make_Set(intx)初始化集合;
Find_Set(intx)查找x元素所在的集合,回溯时压缩路径;
Union(intx,inty,intw)合并x,y所在的集合。
3、克鲁斯卡尔算法的实现
该算法的实现位于主函数中:
qsort(e,n,sizeof(edge),cmp);
//将边排序
printf("
最小生成树的各条边及权值为:
\n"
);
for(i=0;
i<
n;
i++)
{
x=Find_Set(e[i].x);
y=Find_Set(e[i].y);
if(x!
=y)
printf("
%c-%c:
%d\n"
e[i].x+'
A'
e[i].y+'
e[i].w);
Union(x,y,e[i].w);
}
}
4、设计中还包含以下函数:
(1)/*比较函数,按权值(相同则按x坐标)非降序排序*/
intcmp(constvoid*a,constvoid*b)
if((*(edge*)a).w==(*(edge*)b).w)
return(*(edge*)a).x-(*(edge*)b).x;
return(*(edge*)a).w-(*(edge*)b).w;
}
(2)快排函数qsort,包含在stdlib.h头文件里
(3)C语言提供的随机数函数srand(unsignedintseed);
使用随机数函数如下:
srand((unsigned)time(NULL));
for(i=0;
i++)
{
e[i].w=rand()%100+1;
e[i].x=chx-'
;
if(chy==h+48)chx++;
e[i].y=(chy++)-'
if(chy==h+49)chy=chx+1;
Make_Set(i);
输出1~100之间的随机数,使用rand()%100+1。
5、主程序的流程图
三、调试分析
调试过程中遇到的问题:
随机产生权值时,通过边数不能确定起点和终点。
解决:
通过顶点数对所有边取随机数。
四、用户使用说明及测试结果
1、打开界面:
(1)人为输入权值,输入1,回车:
输入7,回车:
输入边的信息及结果如下:
(2)随机生成权值,输入0:
输入顶点数5,结果如下:
五、经验和体会
通过本次课程设计,我学会了利用克鲁斯卡尔算法求最小生成树。
另外学会了利用随机函数产生随机数,以及课本没有提到的边集数组的定义和使用。
六、附录源代码
#include<
stdio.h>
stdlib.h>
#include"
time.h"
#defineMAX435
/*定义边(x,y),权为w*/
edgee[MAX];
/*rank[x]表示x的秩*/
intrank[MAX];
/*father[x]表示x的父节点*/
intfather[MAX];
/*比较函数,按权值(相同则按x坐标)非降序排序*/
/*初始化集合*/
voidMake_Set(intx)
father[x]=x;
rank[x]=0;
/*查找x元素所在的集合,回溯时压缩路径*/
intFind_Set(intx)
while(father[x])
x=father[x];
returnx;
/*合并x,y所在的集合*/
voidUnion(intx,inty,intw)
if(x==y)return;
/*将秩较小的树连接到秩较大的树后*/
if(rank[x]>
rank[y])
father[y]=x;
else
if(rank[x]==rank[y])
{
rank[y]++;
father[x]=y;
/*主函数*/
intmain()
printf("
*最小生成树问题:
inti,n,h,k=0;
charchx,chy;
\n人为输入权值请输入1,随机生成权值请输入0:
scanf("
%d"
&
k);
if(k==1)
/*读取边的数目*/
请输入边的条数(小于436):
scanf("
&
n);
getchar();
/*读取边信息并初始化集合*/
请输入边的信息(起点,终点,权值(<
100))分别用空格隔开:
%c%c%d"
chx,&
chy,&
e[i].w);
getchar();
e[i].x=chx-'
e[i].y=chy-'
else{
请输入顶点数(<
=30):
h);
srand((unsigned)time(NULL));
n=(h-1)*h/2;
chx=49;
chy=50;
随机生成的各条边及权值为:
/*将边排序*/
return0;