数据结构最小生成树问题实习报告.docx
《数据结构最小生成树问题实习报告.docx》由会员分享,可在线阅读,更多相关《数据结构最小生成树问题实习报告.docx(8页珍藏版)》请在冰豆网上搜索。
数据结构最小生成树问题实习报告
数据结构最小生成树问题实习报告
实习报告
题目:
最小生成树问题
班级:
15184112姓名:
张旭学号:
15041638完成日期:
第十一周
一、需求分析
1.问题描述:
在n个城市间建设信网络,只需要架设n-1条线路即可。
以最低的代价建设这个通信网,即求图的最小生成树。
2.基本功能:
程序运用普利姆算法或克鲁斯卡尔算法求网的最小生成树及它们之间的权值,输入各城市的数目以及各个城市之间的距离。
将城市之间的距离当做网中各点之间的权值。
3.输入输出:
输出结果为文本形式的最小生成树和它们之间的权值。
程序演示过程是以用户和计算机对话的形式进行的,即在计算机终端中显示提示信息后,用户自主选择下一步命令,然后计算机显示相应的输入数据和运算结果。
二、概要设计
1.设计思路:
1)给出数据结构的相关定义。
2)采用数组(邻接矩阵)表示法,构造无向网G。
3)用普里姆算法或kruskal的算法构造网G的最小生成树T,输出T的各条边。
克鲁斯卡尔(Kruskal)算法简介:
算法思想:
设连通网N=(V,{E}),令最小生成树
(1)初始状态为只有n个顶点而无边的非连通图T=(V,{}),每个顶点自
成一个连通分量;
(2)在E中选取代价最小的边,若该边依附的顶点落在T中不同的连通分
量上,则将此边加入到中;否则,舍去此边,选取下一条代价最小的边;
(3)依此类推,直至T中所有顶点都在同一连通分量上为止。
2.程序结构设计:
本程序主要包括四个模块:
(1)主程序模块
(2)堆排序模块:
包括heapadjust和heapsort
(3)kruskal算法模块,采用堆排序,有优化
(4)并查集模块:
MFSet
三、详细设计
#include
#include
#include
usingnamespacestd;
structedge
{
intv1,v2,w;
};
structMFSet
{
public:
intset[31];
intn;
voidinitial()
{
for(inti=1;i<=n;i++)
set[i]=i;
}
intfind(inta)
{
returnset[a];
}
boolmerge(inta,intb)
{
intx=set[a];
inty=set[b];
if(x!
=y)
{
set[a]=set[a]--;
set[b]=set[b]--;
}
elsereturnfalse;
returntrue;
}
};
voidswap(edge&a,edge&b)
{
edgetemp;
temp=a;
a=b;
b=temp;
}
voidheapadjust(edge*edges,inti,intn)
{
while(2*i<=n)
{
inttemp=i;
if(edges[i].w>edges[2*i].w)
temp=2*i;
if(2*i+1<=n&&edges[temp].w>edges[2*i+1].w)
temp=2*i+1;
if(temp!
=i)
{
swap(edges[i],edges[temp]);
i=temp;
}
elsebreak;
}
}
voidKruscal(MFSets,edge*edges,inte,intn)
{
for(inti=e/2;i>=1;i--)
{
heapadjust(edges,i,e);
}
intcount=0;
cout<<"路线如下"<intnum=e;
for(inti=1;i<=e;i++)
{
if(s.merge(edges[1].v1,edges[1].v2))
{
cout<<"<"<"<<"weight="<if(++count>=n-1)
{
cout<<"通信网络已建成"<break;
}
}
edges[1]=edges[num];
num--;
heapadjust(edges,1,num);
}
if(countcout<<"但所给线路不足以构成完整的通信网络"<}
intmain()
{
edgeedges[30];
MFSets;
intn;
cout<<"请输入城市数目"<cin>>n;
s.n=n;
s.initial();
inte;
cout<<"请输入线路数目"<cin>>e;
intchoice;
cout<<"选择1人工输入修路代价选择2自动生成修路代价"<cin>>choice;
if(choice==1)
{
cout<<"请输入"<for(inti=1;i<=e;i++)
{
cin>>edges[i].v1>>edges[i].v2>>edges[i].w;
}
}
else
{
srand(time(0));
cout<<"请输入"<for(inti=1;i<=e;i++)
{
cin>>edges[i].v1>>edges[i].v2;
edges[i].w=rand()%99+1;
}
cout<<"各线路对应的修建代价如下"<for(inti=1;i<=e;i++)
{
cout<}
}
Kruscal(s,edges,e,n);
}四、调试与验收
1.在验收时,老师要求不要在kruscal里直接用堆排序,而是直接使用小顶堆来排序。
2.本题目使用的是并查集来进行创建最小生成树,在碰到单枝树时会降低整个程序执行的效率。
五、用户手册
1.根据提示输入相应内容
2.本程序包括两种输入方式,一种是修路的代价用户本人输入,另一种是系统自动随机生
成修路的代价。
3.若成功完成最小生成树的建立则系统提示通信网络已建成,否则会提示所给线路不足以构成完成完整的通信网络。
六、测试结果
七附录
源程序文件名清单:
最小生成树问题.cpp