最小生成树实验指导书.docx
徐州工程学院数据结构最小生成树实验文档
for(j=0;j<G->vexnum-1;++j){ seat = minimize( G,A ); printf("select min: %d\n", seat); A[seat].know = 1; p=G->LH[seat].firstarc; for (p; p != NULL; p=p->nextarc){ i=p->adjvex; if(A[i].know == 0 && p->weight < A[i].lowcost){ A[i].nextvex = G->LH[seat].data; A[i].lowcost = p->weight; } }
}
location = search(G ,u);// 确定 u 元素在头结点数组中的位置 for (p=G->LH[location].firstarc ; p != NULL; p=p->nextarc ){
i = p->adjvex; A[i].nextvex = G->LH[location].data; A[i].lowcost = p->weight; A[i].know = 0; } A[location].know = 1; A[location].lowcost = 0; A[location].nextvex = '0';
// 建图
int search(Graph *G,char a);
int i,n1,n2,w; char a,b; ArcNode *p, *q;
printf(" 请输入顶点个数和边的条数: \n"); scanf("%d %d",&G->vexnum,&G->arcnum); printf(" 请输入顶点信息 \n"); for (i = 0; i < G->vexnum; ++i){
n个城市最小生成树实验报告
数据结构课程设计报告起评分理论成绩实践成绩总成绩院系:专业:班级:学号:姓名:教师:时间:目录一、设计要求 (3)1、问题描述 (3)2、功能 (3)3、数据 (3)二、概述与分析 (3)1、图 (3)2、邻接矩阵 (3)3、生成树 (4)4、最小生成树 (5)5、最小生成树的操作 (5)三、程序设计及分析 (6)四、流程图 (7)1、模块结构流程图 (7)2、Prim算法流程设计 (8)五、测试分析 (8)六、总结 (10)七、源程序代码 (10)一、设计要求:1、问题描述构造可以使n个城市连接的最小生成树。
2、功能给定一个地区的n个城市间的距离网,用Prim算法或Kruskal算法建立最小生成树,并计算得到的最小生成树的代价。
本人采用的是Prim算法。
3、数据城市间的距离网采用邻接矩阵表示(要求至少6个城市,10条边),邻接矩阵的存储结构定义采用课本中给出的定义,若两个城市之间不存在道路,则将相应边的权值设为自己定义的无穷大值。
要求在屏幕上显示得到的最小生成树中包括了哪些城市间的道路,并显示得到的最小生成树的代价。
表示城市间距离网的邻接矩阵(要求至少6个城市,10条边)二、概述与分析1、图图的定义:图G是有两个集合V和E组成,记做G=(V,E),其中V是定点的有限集合,记做V(G),E是连接V的两个不同的顶点的边的有限集合,记做E(G)。
2、邻接矩阵邻接矩阵是图的一种存储方法,它是表示顶点之间相邻关系的矩阵。
设G=(V,E)是具有n(n>0)个顶点的图,顶点的顺序依次为(v0,v1,…,vn-1),则G的邻接矩阵A是n阶方阵,其定义如下。
1)如果G是无向图,则1 (vi,vj) ∈E(G)A[i][j]=0 其他2)如果G是有向图,则1 <vi,vj> ∈E(G)A[i][j]=0其他3)如果G是带权无向图,则w ij vi≠vj且(vi,vj)∈E(G)A[i][j]= 0 vi =vj∞其他4)如果G是带权有向图,则w ij vi≠vj且<vi,vj> ∈E(G)A[i][j]= 0 vi =vj∞其他邻接矩阵的特点如下:1)图的邻接矩阵表示是唯一的。
最小生成树算法实验报告
最小生成树算法实验报告【实验报告】最小生成树算法实验一、实验目的本次实验旨在研究最小生成树算法,通过对比不同的算法,并对实验结果进行分析,探索最小生成树算法的优劣势和适应场景。
二、实验过程1.算法介绍本次实验中我们将使用两种最小生成树算法:普里姆算法和克鲁斯卡尔算法。
- 普里姆算法(Prim算法):从一个顶点开始,不断在剩下的顶点中选择到当前已有的最小生成树的距离最小的边,将该边的另一个顶点加入树中,直到所有的顶点都加入树中。
- 克鲁斯卡尔算法(Kruskal算法):首先将所有边按照权值从小到大进行排序,然后以最小权值的边开始,依次选择权值最小且不会形成环路的边,直到找到n-1条边为止,其中n为顶点数。
2.实验步骤首先,我们使用Python语言实现了普里姆算法和克鲁斯卡尔算法。
然后,我们构造了一些测试用例,包括不同规模的图和不同权值分布的图。
最后,我们对实验结果进行对比分析。
三、实验结果1.测试用例设计我们设计了三个测试用例,分别为小规模图、中规模图和大规模图,具体如下:-小规模图:顶点数为5的图,权值随机分布。
-中规模图:顶点数为50的图,权值随机分布。
-大规模图:顶点数为100的图,权值随机分布。
2.实验结果分析我们的实验结果如下表所示:算法,小规模图,中规模图,大规模图:-------:,:------:,:------:,:------:普里姆算法,13,455,703从实验结果可以看出,对于小规模图和中规模图,普里姆算法的运行时间明显低于克鲁斯卡尔算法。
但是对于大规模图,克鲁斯卡尔算法的运行时间与普里姆算法的运行时间差距不大,甚至略小于普里姆算法。
这是因为克鲁斯卡尔算法中排序边的时间复杂度为O(ElogE),而普里姆算法中筛选最小距离的边的时间复杂度为O(V^2)。
综上所述,普里姆算法适用于较小规模的图,而克鲁斯卡尔算法适用于较大规模的图。
四、实验总结本次实验研究了最小生成树算法,通过对比实验结果,我们发现不同算法在不同规模的图上的表现有所差异。
(完整word版)普里姆算法求最小生成树
沈阳航空航天大学课程设计报告课程设计名称:数据结构课程设计课程设计题目:Prim算法求最小生成树院(系):计算机学院专业:计算机科学与技术(物联网方向)班级:学号:姓名:指导教师:学术诚信声明本人声明:所呈交的报告(含电子版及数据文件)是我个人在导师指导下独立进行设计工作及取得的研究结果。
尽我所知,除了文中特别加以标注或致谢中所罗列的内容以外,报告中不包含其他人己经发表或撰写过的研究结果,也不包含其它教育机构使用过的材料。
与我一同工作的同学对本研究所做的任何贡献均己在报告中做了明确的说明并表示了谢意。
报告资料及实验数据若有不实之处,本人愿意接受本教学环节“不及格”和“重修或重做”的评分结论并承担相关一切后果。
本人签名: 日期:2015 年 1 月15 日沈阳航空航天大学课程设计任务书计算机科学与技术课程设计名称数据结构课程设计专业(物联网方向)学生姓名班级学号题目名称Prim算法生成最小生成树起止日期2015 年 1 月 5 日起至2015 年 1 月16 日止课设内容和要求:在n个城市之间建立网络,只需保证连通即可,求最经济的架设方法,利用Prim算法输出n个城市之间网络图,输出n个节点的最小生成树。
其中,n个城市表示n个节点,两个城市间如果有路则用边连接,生成一个n个节点的边权树,要求键盘输入。
参考资料:算法与数据结构,严蔚敏、吴伟民,清华大学出版社,2006C程序设计,谭浩强,清华大学出版社,2010教研室审核意见:教研室主任签字:指导教师(签名)年月日学生(签名)2015 年 1 月15 日目录学术诚信声明 .............................................................................................................. - 1 -一课程设计目的和要求.......................................................................................... - 4 -1.1课程设计目的 .. (4)1.2课程设计的要求 (4)二实验原理分析 ........................................................................................................ - 5 -2.1最小生成树的定义 (5)2.2P RIM算法的基本思想 (5)三概要分析和设计 .................................................................................................... - 8 -3.1概要分析 . (8)3.2概要设计 (9)四测试结果 ............................................................................................................ - 14 -4.1实验一 . (14)4.2实验二 (14)4.3实验三 (15)参考文献 .................................................................................................................... - 16 -附录(关键部分程序清单).............................................................................. - 17 -一课程设计目的和要求1.1 课程设计目的(一)根据算法设计需要,掌握连通网的数据表示方法;(二)掌握最小生成树的Prim算法;(三)学习独立撰写报告文档。
数据结构 实验8 最小生成树
(1)复习图的存储方法和图的遍历方法;
(2)进一步掌握图的非线性特点、递归特点和动态特性;
(3)掌握最小生成树的求解算法。
2、实验内容
(1)用Prim算法求最小生成树;
(2)输入网的二维矩阵,输出最小生成树;
3、实验要求
(1)分析算法思想,利用C(C++)语言完成程序设计。
(2)上机调试通过实验程序。
if(g[k][j]<lowcost[j])
{lowcost[j]=g[k][j];
closest[j]=k;
}
printf("\n");
}
}
int adjg(int g[][max]) //建立无向图
{
int n,e,i,j,k,v1,v2,weight;
printf("输入顶点个数,边的条数:");
⑵源代码
#include <stdio.h>
#define inf 9999
#define max 40
void prim(int g[][max],int n) // prim的函数
{
int lowcost[max],closest[max];
int i,j,k,min;
for(i=2;i<=n;i++) // n个顶点,n-1条边
scanf("%d,%d",&n,&e);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
g[i][j]=inf; //初始化矩阵,全部元素设为无穷大
for(k=1;k<=e;k++)
最小生成树实验指导书.docx
实验1采用普里姆(prim)算法构造网络的最小生成树1、实验目的:深入理解最小生成树的概念,熟练掌握普里姆(prim)算法的工作过程,并通过定义合适的数据结构,釆用C语言程序实现。
2、实验内容:根据模板程序编制普里姆算法的程序,在计算机中进行调试,同时寻找两个结点大于6的网络,利用文件读入其邻接矩阵,运行程序。
记录运行结果,并把运行结果与手工生成的结果进行比较,验证程序的正解性。
要求从文本文件中读入网络的邻接矩阵。
3、实验原理①p rim算法的主要步骤②数据表示③算法实现细节4、实验步骤与实验结果①编写"im算法的C语言程序②输入计算机进行调试③准备两个顶点大于6的网络,把网络的邻接矩阵输入文本文件中,运行程序,记录程序的运行结果,根据结果画出最小生成树,并与手工生成的最小生成树进行比较。
实验结果:①画出网络图,写出相应的邻接矩阵②记录程序的运行结果,根据结果画出最小生成树并写出最小生成树的权值。
附录:程序模板#i nclude <std i o.h>/*定义一个结构体,用于记录一条边的始点与终点*/typedef struct pp{int p, q;} edge;i nt g [100] [100], u [100], v [100], vexnum;edge p[100] ;//用于记录最小生成树的各条边void input ()//读入图的邻接矩阵{i nt i, j, temp;FILE *fp;fp=fopen ("pp5. txt", " r");fscanf (fp,"%d",&vexnum);for (i=1;i<=vexnum;i++){printf(H\n n);for (j=1;j<=vexnum;j++){fscanf (fp, "%d", &temp);g[i] [jl=temp;pr i ntf (”%d ", temp);}}fclose (fp);}ma i n (){i nt i, j, k, m, n, ma, s=0;inputO;//输入数据for (ih ; iUvexnum; i++)//集合V中包含了所有顶点v[i]二 1 ;u[1]=1 ;v[1]=0;//第1个节点加入至集合U中,并从集合V中去掉for (i=1; i<=vexnum-1 ; i ++) //最多需vexnum-1 条边{〃以下找连接节点集U至节点集V的最小边ma=1000;//ma存放最小边的权值for (j=1;j<=i;j++)//集合U中的第j个节点,其编号为u[j],每次增加一个,共for (k=1;k<=vexnum;k++)/*v[k]!=0表示节点k在集合V中;g[u[j][k]>0表示有边*/ if(v[k] !=0&&ma>g[u[j]] [k]&&g[u[j]] [k]>0){ma二g[u[j]] [k] ;//保存最小边值m二u[j] ;//最小边的始点编号n二k;//最小边的终点编号}s=s+ma; // 求和u[i+1]=n;v[n]=0;//把找到最小边的终点编号从V中去掉,并加入至U中p[i]. p二m;p[i]. q二n;//保存最小边的始点编号与终点编号}printfC'\n H);for (i=1;i<=vexnum-1;i++)pr intf ("\n%d %d %d", p[i]. p, p[i]. q, g[p[i]. p] [p[i]. q]);printf("\nsum=%d\n\n",s);采用克鲁斯卡尔(kruskal)M法构造网络的最小生成树实验21、实验目的:深入理解最小生成树的概念,熟练掌握克鲁斯卡尔(kruskal)算法的工作过程,并通过定义合适的数据结构,采用C语言程序实现。
数据结构实验报告-最小生成树(精选5篇)
数据结构实验报告-最小生成树(精选5篇)第一篇:数据结构实验报告-最小生成树电子科技大学实验报告学生姓名:XXX 学号:20***指导教师:刘峤实验地点:信软楼306实验时间:5月17日一、实验室名称:软件实验室二、实验项目名称:数据结构与算法—图三、实验学时:4四、实验原理:Kruskal 算法是一种按照图中边的权值递增的顺序构造最小生成树的方法。
其基本思想是:设无向连通网为G=(V,E),令G 的最小生成树为T,其初态为T=(V,{}),即开始时,最小生成树T 由图G 中的n 个顶点构成,顶点之间没有一条边,这样T 中各顶点各自构成一个连通分量。
然后,按照边的权值由小到大的顺序,考察G 的边集E 中的各条边。
若被考察的边的两个顶点属于T 的两个不同的连通分量,则将此边作为最小生成树的边加入到T 中,同时把两个连通分量连接为一个连通分量;若被考察边的两个顶点属于同一个连通分量,则舍去此边,以免造成回路,如此下去,当T 中的连通分量个数为1 时,此连通分量便为G 的一棵最小生成树。
如教材153页的图4.21(a)所示,按照Kruskal 方法构造最小生成树的过程如图4.21 所示。
在构造过程中,按照网中边的权值由小到大的顺序,不断选取当前未被选取的边集中权值最小的边。
依据生成树的概念,n 个结点的生成树,有n-1 条边,故反复上述过程,直到选取了n-1 条边为止,就构成了一棵最小生成树。
五、实验目的:本实验通过实现最小生成树的算法,使学生理解图的数据结构存储表示,并能理解最小生成树Kruskal 算法。
通过练习,加强对算法的理解,提高编程能力。
六、实验内容:(1)假定每对顶点表示图的一条边,每条边对应一个权值;(2)输入每条边的顶点和权值;(3)输入每条边后,计算出最小生成树;(4)打印最小生成树边的顶点及权值。
七、实验器材(设备、元器件):八、数据结构及程序#include #include #include typedefstruct {intvex;intgno;}TVex,*TpVex;typedefstruct {intvhead, vtail;intwght;intflag;}TEdge,*TpEdge;typedef struct{TpVex VexList;TpEdge EdgeList;int nvex, nedge;}TGraph, *TpGraph;void begin(TpGraph G){ int i;for(i=1;i<=G->nvex;i++){G->VexList[i-1].gno=i;G->EdgeList[i-1].flag=0;} } int findmin(TpGraph G){ int i,j;int minwght=G->EdgeList[0].wght;for(i=0,j=-1;inedge;i++){ PC机一台,装有C/C++语言集成开发环境。
最小生成树实验报告
一、实验目的1. 通过上机程序,进一步加深对最小生成树的理解。
2. 掌握Kruskal算法。
3. 学会用程序解决离散数学中的问题。
4. 增强我们编写程序的能力。
二、实验内容求带权无向联通平面图的最小生成树三、实验环境我的实验依旧是在实验环境下完成的,而所设计的程序也在这个环境下通过了编译,运行和测试。
四、实验原理和实现过程利用Kruskal算法求最小生成树,原理如下:1.选取最小权边e1,置边数j 1.2.i=n-1结束,否则转c。
3.设已经选择的边为e1,e2,......,ei,在G中选取不同于e1,e2, (i)边,使{e1,e2,……,ei,ei+1}中无回路且ei+1是满足此条件的最小边。
4.i i+1,转b。
根据这个,还有以下思路:由G生成的最小生成树T所包含的边的集合1.按非降序权重将E中的边排序2.建立n个单元素集(每个顶点一个)3.最小生成树的边集合T初始为空4 .while |T|<n-15. 令e(x,y)为E中的下一条边6. if包含x的集合不是与包含y的集合不是同一个集合 then7. 将e(x,y)加入到T8. 将包含x的集合和包含y的集合合并9. end ifwhile五、实验源代码及分析#include<>struct Edge{int from, to, weight; rom); o);if(x!=y) rom, edge[k].to, edge[k].weight); rom, &edge[i].to, &edge[i].weight); eight>edge[j].weight){temp=edge[i];edge[i]=edge[j];edge[j]=temp;}printf("The minimum spanning tree is:\n");Kruskal(); //调用Kruskal算法return 0;}其中运用seek函数找出当前端点所在集合编号。
求最小生成树(Kruskal算法)实验报告【范本模板】
学生实验报告学院:软件与通信工程学院课程名称:离散数学(软件)专业班级:12软件2班姓名:杨滨学号:0123707学生实验报告(2) 学生姓名杨滨 学号 0123707 同组人 实验项目 求最小生成树(Kruskal 算法)□必修 □选修 □演示性实验 □验证性实验 □操作性实验 □综合性实验 实验地点W101 实验仪器台号 指导教师 赵晓平 实验日期及节次 2013。
12。
12(四) 89A 节一、实验综述1、实验目的及要求(1)了解求最优化问题的贪心算法,了解贪心法的基本要素,学会如何使用贪心策略设计算法;(2)掌握Prim 算法和Kruskal 算法的思想及两者之间的区别;(3)编写程序,分别利用Prim 算法和Kruskal 算法实现,求出最小代价生成树,输出构成最小代价生成树的边集.实验要求:给出如右图的边权图,求最小生成树.认真完成实验题,能正确运行,提交实验报告并上传程序,实验报告要求写出操作步骤、结果、问题、解决方法、体会等.2、实验仪器、设备或软件计算机、VC++6。
0、office 、相关的操作系统等.二、实验过程(实验步骤、记录、数据、分析)#include<stdio.h 〉#define VERTS 6struct edge {int from ,to; //起顶点,终顶点int find ,val ; //标记,顶点间边长struct edge *next; };typedef struct edge node;node *find_min_cost(node *);void min_tree(node *);√ √int v[VERTS+1]={0};//记录顶点即下标,值即出现过的次数void main(){int data[10][3]={{1,0,6},{0,3,5},{3,5,2},{5,4,6},{4,1,3},{2,1,5},{2,0,1},{2,3,5},{2,5,4},{2,4,6}};//表示有10条线,例如{1,0,6}表示1和0距离为6node *head,*ptr,*new_node;head=NULL;printf(”Add graph:\n”);for (int i=0; i<10; i++){for (int j=1;j<=VERTS;j++){if (data[i][0]==j){new_node=new node;new_node—>from=data[i][0];new_node—〉to=data[i][1];new_node—〉val=data[i][2];new_node—>find=0;new_node-〉next=NULL;if (head==NULL){head=new_node;head-〉next=NULL;ptr=head;}else{ptr-〉next=new_node;ptr=ptr-〉next;}}}}for (ptr=head; ptr!=NULL; ptr=ptr—>next)printf("Begin[%d]\tEnd[%d]\t\tPath[%d]\n”,ptr-〉from,ptr—〉to,ptr-〉val);printf("\nAdd Min Tree:\n”);min_tree(head);putchar('\n');}void min_tree(node *head) //建立最小生成树{node *ptr,*tmptr;int result=0;//布尔值,是否做出输出结果for (ptr=head;ptr!=NULL;ptr=ptr—〉next) //遍历十条边{tmptr=find_min_cost(head); //找出最小边顶点v[tmptr-〉from]++;//当前起点已选自加1次v[tmptr—〉to]++; //当前终点已选自加1次if (v[tmptr—>from]〉1 &&v[tmptr->to]>1){/*这个IF语句就是一个防止生成树中有回路;因为v[tmptr->from]与v[tmptr—〉to]都出现过一次,这棵树的叶子结点都为1,所以当两个结点同时为2时,就形成回路*/v[tmptr—〉from]——;v[tmptr—>to]--;result=1;}else result=0;if (result==0)printf("Begin[%d]\tEnd[%d]\t\tPath[%d]\n",tmptr—〉from,tmptr->to,tmptr—〉val);}}node *find_min_cost(node *head) //最小边查找{int min_val=100;node *ptr,*tmptr;for (ptr=head;ptr!=NULL;ptr=ptr-〉next){if (ptr->val<min_val && ptr-〉find==0) //当当前边最小时并当前顶点没有被选择过{min_val=ptr->val;tmptr=ptr;}} //整个循环遍历完毕找到最小连min_valtmptr->find=1; //并标记该顶的边已选择return tmptr;}三、结论1、实验结果2、分析讨论在编写这个程序时,我们先要非常熟悉kruskal算法,kruskal算法总共选择n—1条边,所使用的贪婪准则是:从剩下的边中选择一条不会产生环路的具有最小耗费的边加入已选择的边的集合内。
数据结构实验最小生成树
数据结构实验最小生成树数据结构实验报告最小生成树问题一、问题描述:若要在n个城市之间建设通信网络,只需要架设n-1条线路即可。
如何以最低的经济代价建设这个通信网,是一个网的最小生成树问题基本要求(1)从文件中读入图的信息。
(2)利用克鲁斯卡尔算法求网的最小生成树。
(3)以文本形式生成树中各条边以及他们的权值。
二(需求分析:1、需定义结构体数组,根据权值逐一选择边。
三(概要设计抽象数据类型:需定义结构体数组,存储每条边的起点,终点,权值。
算法的基本思想:1、图的信息的读取:定义结构体数组,存储每条边的起点,终点,权值。
2、对每条边在数组中的位置处理:选边需从最小的开始,故按边的权值从小到大进行排序。
3、边的选取: 从最小的边的开始,若边的两端点不属于同一集合,则选取该边。
并将该边的两个顶点所在的两个集合合并成为一个。
因为有n个顶点,故只需选取n-1条边。
程序的流程:(1) 输入模块: 读入图的信息(顶点和边,用结构体数组进行存储)。
(2) 处理模块:Kruskal算法。
(3) 输出模块:将结果输出。
四(详细设计:算法的具体步骤:struct G{int fromvex;int endvex;int weight;}GE[100],cur[100];void swap(G* GE,int i,int j){ //交换函数int temp=GE[i].fromvex;GE[i].fromvex=GE[j].fromvex;GE[j].fromvex=temp;temp=GE[i].endvex;GE[i].endvex=GE[j].endvex;GE[j].endvex=temp;temp=GE[i].weight;GE[i].weight=GE[j].weight;GE[j].weight=temp;}void Kruskal(int n){int i,j,k=0,pos=-1,m1,m2;bool** s=new bool *[n];//定义一个二维数组,用来判断是否为同一类for(i=0;i<n;i++)s[i]=new bool[n];for(i=0;i<n;i++){for(j=0;j<n;j++){if(i==j)s[i][j]=true; //初始化数组elses[i][j]=false;}}while(k<n-1){for(i=0;i<n;i++){if(s[i][GE[k].fromvex]==1)m1=i;if(s[i][GE[k].endvex]==1)m2=i;}if(m1!=m2){//判断是否为同一类,如果为同一类(该类中所有的点到起点和终//点的边在s 数组中赋为1),cur[++pos].fromvex=GE[k].fromvex;cur[pos].endvex=GE[k].endvex;cur[pos].weight=GE[k].weight;for(i=0;i<n;i++){if(s[m1][i] || s[m2][i])//把该点添加到该类,并和并两个类s[m1][i]=1;elses[m1][i]=0;s[m2][i]=0;}}k++;}for(i=0;i<n;i++){delete []s[i];}}int main(){int i,j;int numVertex,numEdge;cout<<"请输入点的个数和边的条数:"<<endl; cin>>numVertex>>numEdge;cout<<"请输入边的起始位置和边的权值:"<<endl;for(i=0;i<numEdge;i++)cin>>GE[i].fromvex>>GE[i].endvex>>GE[i].weight;for(i=0;i<numEdge;i++)for(j=i;j<numEdge;j++){if(GE[j].weight<GE[i].weight)//将边的权值按从小到大排列swap(GE,i,j);}Kruskal(numEdge);for(i=0;i<numVertex-1;i++) cout<<cur[i].fromvex<<"->"<<cur[i].endvex<<":"<<cur[i].weight<<endl;system("pause");return 0;}五(调试分析:将选边的过程输出来检验算法的正确性。
实验八 图的最小生成树
浙江大学城市学院实验报告课程名称数据结构与算法实验项目名称实验八图的最小生成树实验成绩指导老师(签名)日期一. 实验目的和要求1.掌握图的最小生成树的概念。
2.掌握生成最小生成树的Prim算法(用邻接矩阵表示图)。
二. 实验内容1、编写用邻接矩阵表示无向带权图时图的基本操作的实现函数,主要包括:①初始化邻接矩阵表示的无向带权图void InitMatrix(adjmatrix G); ②建立邻接矩阵表示的无向带权图void CreateMatrix(adjmatrix G, int n)(即通过输入图的每条边建立图的邻接矩阵); ③输出邻接矩阵表示的无向带权图void PrintMatrix(adjmatrix G, int n) (即输出图的每条边)。
把邻接矩阵的结构定义以及这些基本操作实现函数存放在头文件Graph1.h中。
2、编写生成最小生成树的Prim算法函数void Prim(adjmatrix G, edgset CT,int n)以及输出边集数组的函数void PrintEdge(edgeset CT, int n)。
3、编写测试程序(即主函数),通过调用上述函数首先建立并输出无向带权图,然后生成最小生成树并输出(即输出边集)。
要求:把边集数组的结构定义、Prim算法函数、输出边集数组的函数PrintEdge 以及主函数存放在文件test8.cpp中。
测试数据如下:4、填写实验报告,实验报告文件取名为report8.doc。
5、上传实验报告文件report8.doc与源程序文件test8.cpp及Graph1.h到Ftp 服务器上自己的文件夹下。
三.函数的功能说明及算法思路函数:void InitMatrix(adjmatrix GA)功能:初始化邻接矩阵表示的无向带权图函数:void CreateMatrix(adjmatrix GA,int n)功能:建立邻接矩阵表示的无向带权图函数:void PrintMatrix(adjmatrix GA,int n)功能:输出邻接矩阵表示的无向带权图函数:void Prim(adjmatrix GA,edgeset CT,int n)功能:生成最小生成树思路:设从连通带权图G = { V, E }中的某一顶点u0 出发;选择与它关联的具有最小权值的边<u0, v>,将其顶点加入到生成树的顶点集合U中;以后每一步从一个顶点在U中,而另一个顶点在V-U中的各条边中选择权值最小的边<u, v>,把该顶点加入到集合U中;如此继续下去,直到图中的所有顶点都加入到生成树顶点集合U中为止。
最小生成树数据结构实验报告【范本模板】
数据结构实验报告名称:最小生成树班级:122姓名:*****学号:***********指导老师:********一、设计目的与任务1。
1课程设计目的本课程设计的目的是了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;提高综合运用所学的理论知识和方法独立分析和解决问题的能力;训练用系统的观点和软件开发一般规范进行软件开发。
1。
2课程设计的任务问题描述:已知一个无向连通网表示n个城市以及城市间可能设置的通信线路,其中网的顶点表示城市,边表示两个城市之间的线路,赋于边上的权值表示相应的代价.对于n个点的连通网能建立许多不同的生成树,每一棵生成树都可以是一个通信网。
我们要选择一棵生成树,使总的耗费最小。
二、设计方案2。
1需求分析(1)建立一个图,其存储方式可以采用邻接矩阵形式或者邻接表;(2)利用普利姆算法或者克鲁斯卡尔算法求出网的最小生成树;(3)输入各城市的数目以及各个城市之间的距离。
将城市之间的距离当做网中各点之间的权值。
按顺序输出生成树中各条边以及它们的权值。
2.2数据结构分析构造最小生成树的方法:最初生成树为空,即没有一个结点和一条边,首先选择一个顶点作为生成树的根,然后每次从不在生成树中的边中选择一条权值尽可能小的边,为了保证加入到生成树中的边不会造成回路,与该边邻接的两个顶点必须一个已经在生成树中,一个则不在生成树中,若网中有n个顶点(这里考虑的网是一个连通无向图),则按这种条件选择n—1边就可以得到这个网的最小生成树了。
详细的过程可以描述为:设置2个集合,U集合中的元素是在生成树中的结点,V—U集合中的元素是不在生成树中的顶点。
首先选择一个作为生成树根结点的顶点,并将它放入U集合,然后在那些一端顶点在U集合中,而另一端顶点在V-U集合中的边中找一条权最小的边,并把这条边和那个不在U集合中的顶点加入到生成树中,即输出这条边,然后将其顶点添加到U集合中,重复这个操作n-1次。
数据结构-最小生成树实验报告
#include<stdio.h>#include<stdlib.h>#define MAXLEAF 100#define INF 100000#define EDGENUMBER MAXLEAF*MAXLEAF/2typedef int EdgeType;typedef int VertexType;typedef struct{EdgeType val[MAXLEAF][MAXLEAF];VertexType ves[MAXLEAF];int v;int e;}MGraph;typedef struct{int vex1,vex2;int w;}kedge;void creat_MGraph(MGraph *M){int i,j,k;int w;printf("请输入图的顶点个数及边数:\n");scanf("%d%d",&(M->v),&(M->e));printf("请依次填充顶点信息:\n");for(i=0;i<M->v;i++)scanf("%d",&(M->ves[i]));for(i=0;i<M->v;i++)for(j=0;j<M->v;j++)if(i==j) M->val[i][j]=0;else M->val[i][j]=INF;printf("请依次输入图的边两个顶点顶点的权值:(格式:a b c)\n");for(k=0;k<M->e;k++){scanf("%d%d%d",&i,&j,&w);M->val[i-1][j-1]=w;M->val[j-1][i-1]=w;}}VertexType kruskal(MGraph M){int tag[MAXLEAF];kedge Ke[EDGENUMBER];int i,j;VertexType length=0;int n=0;for(i=0;i<M.v;i++) tag[i]=i;for(i=0;i<M.v;i++)for(j=i+1;j<M.v;j++)if(M.val[i][j]!=INF){Ke[n].vex1=i;Ke[n].vex2=j;Ke[n++].w=M.val[i][j];}kedge temp;for(i=0;i<n-1;i++)for(j=0;j<n-i-1;j++)if(Ke[j].w>Ke[j+1].w){temp=Ke[j+1];Ke[j+1]=Ke[j];Ke[j]=temp;}for(i=0;i<n;i++){int first,second;first = tag[Ke[i].vex1];second = tag[Ke[i].vex2];if(first!=second){length+=Ke[i].w;printf("%d->%d: %d\n",Ke[i].vex1,Ke[i].vex2,Ke[i].w);tag[Ke[i].vex2]=first;for(j=0;j<M.v;j++){if(second==tag[j])tag[j]=first;}}}return length;}int main(){MGraph M;int len;creat_MGraph(&M);printf("最小生成树:\n");len=kruskal(M);printf("最小成本:%d",len);return 0;}。
实验七 最小生成树
实验七最小生成树一实验目的1.掌握最小生成树的概念2.掌握Prim算法生成最小生成树的方法3. 了解Kruskal算法生成最小生成树的方法二实验内容建立一个无向网,并分别用Prim算法构造最小生成树。
三参考程序/*实验7:最小生成树-prim*/#include <stdio.h>#include <conio.h>#include <string.h>#define INFINITY 9999 /*无穷大*/#define MAX_VERTEX_NUM 26 /*最大顶点数*/#define MAX_NAME 5 /*顶点字符串的最大长度*/typedef enum {DG,DN,UDG,UDN} GraphKind;typedef char VertexType[MAX_NAME]; /*顶点类型*/typedef int VRType; /*顶点关系类型*/#define MAXSIZE 100#define NULL 0#define OK 1#define ERROR 0typedef int Status;typedef char ElemType;typedef struct{VRType adj;}Arcclosedgell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef struct{VertexType vexs[MAX_VERTEX_NUM]; /*顶点向量*/AdjMatrix arcs; /*邻接矩阵*/int vexnum,arcnum; /*图的当前顶点数和弧数*/GraphKind kind; /*图的种类标志*/} Mgraph;typedef struct{VertexType adjvex;VRType lowcost;}minside[MAX_VERTEX_NUM];int LocateVex(Mgraph *G,VertexType u) /*查找顶点u*/ {int i;for(i=0;i<G->vexnum;i++)if(strcmp(u,G->vexs[i])==0)return i;return -1;}void PrintGraph(Mgraph *G) /*输出邻接矩阵存储的图*/ {int i,j;printf("%d vexs,%d arcs\n",G->vexnum,G->arcnum);for(i=0;i<G->vexnum;i++)printf("%s ",G->vexs[i]);printf("\nG->arcs.adj\n");for(i=0;i<G->vexnum;i++){for(j=0;j<G->vexnum;j++)printf("%5d",G->arcs[i][j].adj);printf("\n");}}void CreateUDN(Mgraph *G) /*创建无向网*/{int i,j,k,w;VertexType va,vb;printf("please enter vexnum && arcnum:");scanf("%d%d",&G->vexnum,&G->arcnum);printf("please enter vertex:");for(i=0;i<G->vexnum;i++)scanf("%s",G->vexs[i]);for(i=0;i<G->vexnum;i++)for(j=0;j<G->vexnum;j++)G->arcs[i][j].adj=INFINITY;printf("enter %d arcs:\n",G->arcnum);for(k=0;k<G->arcnum;k++){scanf("%s%s%d%c",va,vb,&w);i=LocateVex(G,va);j=LocateVex(G,vb);G->arcs[i][j].adj=G->arcs[j][i].adj=w;}G->kind=UDN;}int minimum(minside SZ,Mgraph *G) /*求SZ.lowcost的最小值,并返回其在SZ中的序号*/{int i=0,j,k,min;while(!SZ[i].lowcost)i++;min=SZ[i].lowcost;k=i;for(j=i+1;j<G->vexnum;j++)if(SZ[j].lowcost>0&&min>SZ[j].lowcost){min=SZ[j].lowcost;k=j;}return k;}void Prim(Mgraph *G,VertexType u){minside closedge;int i,j,k;k=LocateVex(G,u);for(j=0;j<G->vexnum;++j){strcpy(closedge[j].adjvex,u);closedge[j].lowcost=G->arcs[k][j].adj;}closedge[k].lowcost=0;printf("Each side of Minimum spanning tree:\n" );for(i=1;i<G->vexnum;++i){k=minimum(closedge,G);printf("(%s--%s)\n",closedge[k].adjvex,G->vexs[k]);closedge[k].lowcost=0;for(j=0;j<G->vexnum;++j)if(G->arcs[k][j].adj<closedge[j].lowcost){strcpy(closedge[j].adjvex,G->vexs[k]);closedge[j].lowcost=G->arcs[k][j].adj;}}}void main()Mgraph G;clrscr();CreateUDN(&G);PrintGraph(&G);Prim(&G,G.vexs[0]);}/*实验7:最小生成树-kruskal*/#include <stdio.h>#include <conio.h>#define INFINITY 9999 /*无穷大*/#define MAX_VERTEX_NUM 26 /*最大顶点数*/#define MAX_NAME 5 /*顶点字符串的最大长度*/typedef enum {DG,DN,UDG,UDN} GraphKind;typedef char VertexType[MAX_NAME]; /*顶点类型*/ typedef int VRType; /*顶点关系类型*/#define MAXSIZE 100#define NULL 0#define OK 1#define ERROR 0typedef int Status;typedef char ElemType;typedef struct{VRType adj;}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef struct{VertexType vexs[MAX_VERTEX_NUM]; /*顶点向量*/AdjMatrix arcs; /*邻接矩阵*/int vexnum,arcnum; /*图的当前顶点数和弧数*/GraphKind kind; /*图的种类标志*/} Mgraph;int LocateVex(Mgraph *G,VertexType u) /*查找顶点u*/ {int i;for(i=0;i<G->vexnum;i++)if(strcmp(u,G->vexs[i])==0)return i;return -1;}void PrintGraph(Mgraph *G) /*输出邻接矩阵存储的图*/ {int i,j;printf("%d vexs,%d arcs\n",G->vexnum,G->arcnum);for(i=0;i<G->vexnum;i++)printf("%s ",G->vexs[i]);printf("\nG->arcs.adj\n");for(i=0;i<G->vexnum;i++){for(j=0;j<G->vexnum;j++)printf("%5d",G->arcs[i][j].adj);printf("\n");}}void CreateUDN(Mgraph *G) /*创建无向网*/{int i,j,k,w;VertexType va,vb;printf("please enter vexnum && arcnum:");scanf("%d%d",&G->vexnum,&G->arcnum);printf("please enter vertex:");for(i=0;i<G->vexnum;i++)scanf("%s",G->vexs[i]);for(i=0;i<G->vexnum;i++)for(j=0;j<G->vexnum;j++)G->arcs[i][j].adj=INFINITY;printf("enter %d arcs:\n",G->arcnum);for(k=0;k<G->arcnum;k++){scanf("%s%s%d%c",va,vb,&w);i=LocateVex(G,va);j=LocateVex(G,vb);G->arcs[i][j].adj=G->arcs[j][i].adj=w;}G->kind=UDN;}void Kruskal(Mgraph G) /*克鲁斯卡尔算法求最小生成树*/ {int set[MAX_VERTEX_NUM],i,j;int k=0,a=0,b=0,min=G.arcs[a][b].adj;for(i=0;i<G.vexnum;i++)set[i]=i;printf("The side of MST:\n");while(k<G.vexnum-1){for(i=0;i<G.vexnum;++i)for(j=i+1;j<G.vexnum;++j)if(G.arcs[i][j].adj<min){min=G.arcs[i][j].adj;a=i;b=j;}min=G.arcs[a][b].adj=INFINITY; /*删除上三角中该边*/ if(set[a]!=set[b]){printf("%s-%s\n",G.vexs[a],G.vexs[b]);k++;for(i=0;i<G.vexnum;i++)if(set[i]==set[b])set[i]=set[a];}}}void main(){Mgraph G;clrscr();CreateUDN(&G);PrintGraph(&G);Kruskal(G);}。
实验2最小生成树
实验二最小生成树一、源代码#include<stdlib.h>#include<stdio.h>#include<string.h>struct EDGE{ int pointone, pointtwo, quan; /*定义一个结构,存放点和边以及边上的权值的关系*/};EDGE end[50], temp; /*用定义的数据结构来定义一个数组和一个变量*/int i, j, k, n, m;int p[100], r[100];int find(int x){if(p[x] == x)return x;elsereturn p[x] = find(p[x]);}int Kruskal(){int x, y;for(i = 0; i < 100; i++) /*初始化并查集初始化边序号*/p[i] = r[i] = i;for(i = 0; i < m; i++){k = r[i];x = find(end[k].pointone); /*找出当前边两个断电所在集合编号*/y = find(end[k].pointtwo); /*如果在不同集合,合并*/if(x != y){printf("[%d, %d] (%d)\n",end[k].pointone, end[k].pointtwo, end[k].quan);/*输出这时的点和边的关系*/ p[x] = y;}}return 0;}int main(){ while(1){ scanf("%d %d",&n, &m); /*输入有n个节点m条边*/for(i = 0; i < m; i++){scanf("%d %d %d",&end[i].pointone, &end[i].pointtwo, &end[i].quan); /*把结点和边的关系输进去 */}for(i = 0; i < m-1; i++) /*利用冒泡排序法进行排序*/{ for(j = i+1; j < m; j++){if(end[i].quan > end[j].quan){temp = end[i];end[i] = end[j];1end[j] = temp;} /*对边的权值进行从小到大的排列*/ }}Kruskal(); /*调用Kruskal函数*/ }return 0;}二、测试用例8 131 2 31 6 21 4 12 4 12 7 32 3 22 5 23 5 43 8 34 7 25 7 16 7 27 8 2输出:[1, 4] (1)[2, 4] (1)[5, 7] (1)[2, 3] (2)[2, 5] (2)[1, 6] (2)[7, 8] (2)自定义用例:输入:6 1121 2 111 4 21 5 61 6 12 3 82 4 72 6 93 4 53 5 104 5 45 6 3输出:[1, 6] (1)[1, 4] (2)[5, 6] (3)[3, 4] (5)[2, 4] (7)三、解题报告输入:首先输入点的个数和边的个数,输入有n个节点n条边;接着输入点和边得关系;运算:然后利用函数调用的方式调用Kruskal算法首先选取最小权值的边为e1,并赋值i为1;接下来设已经选择的边为e1,e2,e3,…,ei,在图中选择不同于前面所提到的边ei+1,使得{e1,e2,…,ei.ei+1}中无回路且ei+1是满足此条件的最小权值边。
【报告】最小生成树算法实验报告
【关键字】报告最小生成树算法➢问题描述设G=(V,E)是一个无向连通带权图,E中每条边(v,w)的权为c(v,w)。
如果G的一个子图G`是一棵包含G的所有顶点的书,则称G`为G的生成树。
生成树上各边权的总和称为该生成树的耗费,在G的所有生成树中,耗费最小的生成树就称为G的最小生成树。
给定一个无向连通带权图,构造一个最小生成树。
➢设计思想利用Prim算法求最小生成树,Prim算法是利用贪心策略设计的算法。
设G=(V,E)是一个连通带权图,V={1,2,…,n}。
构造G的一棵最小生成树的Prim算法的基本思想是:首先置U={1},然后,只要U是V的真子集,就做如下的贪心选择:选取满足条件i∈U,j∈V-U,且使c(i,j)达到最小的边(i,j),并将顶点j添加到U中。
这个过程一致进行到U=V时为止。
在这个过程中选取到的所有边恰好构成G的一棵最小生成树。
➢时间复杂度Prim算法的Pascal语言描述如下:Procedure PRIM(c:array[1..n,1..n] of real);Varlowcost:array[1..n] of real;closest:array[1..n] of integer;i,j,k,min,integer;begin(1)for i:=2 to n do(2)begin{初始化,此时U只含有顶点1}(3)lowcost[i]:=c[1,i];(4)Closest[i]:=1;(5)end;(6)for i:=2 to n do(7)begin {寻找顶点分别在V-U与U中边权最小的边}(8)min:=lowcost[i];(9)j:=i;(10)For k:=2 to n do(11)If lowcost[k]<min then(12)Begin(13)Min:=lowcost[k];(14)j:=k;(15)End;(16)print(j,closest[j]);{输出找到的边}(17)Lowcost[j]:=∞;{将j添加到U}(18)For k:=2 to n do {调整lowcost和closest}(19)if(c[j,k]<lowcost[k])and(lowcost[k]< ∞)then(20)Begin(21)Lowcost[k]:=c[j,k];(22)Closest[k]:=j;(23)End(24)End(25)End;{PRIM}上述过程中第(6)~(24)行的for循环要执行n-1次,每次执行时,第(10)~(15)行和第(18)~(23)行的for循环都要O(n)时间,所以Prim算法所需的计算时间为O(n)。
数据结构实验报告最小生成树参考模板
HUNAN UNIVERSITY 课程实习报告
题目:最小生成树
学生姓名:
学生学号:
专业班级:
指导老师:
完成日期:
一、需求分析
若要在n个城市之间建设通信网络,只需要架设n-1条线路即可。
如何以最低的经济代价建设这个通信网,是一个网的最小生成树问题
二、概要设计
抽象数据类型
用数组将边的距离及权值进行存储并排序。
算法的基本思想
构造生成树的网一定是无向网。
并设顶点数不超过30个,边权值为小于100的整数。
根据克鲁斯卡尔算法的特点,为便于选择选择权值小的边,存储结构不选用邻接矩阵和邻接表,而是可以用存储边(带权)的数组表示图。
程序的流程
程序由三个模块构成:
(1)从文件中读入图的信息。
(2)利用克鲁斯卡尔算法求网的最小生成树。
(3)以文本形式生成树中各条边以及他们的权值。
三、
四、详细设计
算法的具体步骤
先将用户的输入的顶点和边的数量,根据这些信息构建出图的结构,最后对边的权值进行排序。
输入和输出的格式
输入:
输入顶点和边的个数及顶点之间的权值。
输出:
输出最小生成树的序列。
五、测试结果
六、实验心得
实验的时候不是这个结果啊,可能是哪个环节出了错误,但是思想没有问题的,通过本次实验学会了用C++实现最小生成树。
友情提示:范文可能无法思考和涵盖全面,供参考!最好找专业人士起草或审核后使用,感谢您的下载!。
最小生成树算法实验报告_2
作业1最小生成树的生成算法1.1算法应用背景在实际生活中, 图的最小花费生成树问题有着广泛的应用。
例如, 用图的顶点代表城市, 顶点与顶点之间的边代表城市之间的道路或通信线路, 用边的权代表道路的长度或通信线路的费用, 则最小花费生成树问题, 就表示为城市之间最短的道路或费用最小的通信线路问题。
其中普里姆算法是使用贪婪法策略设计的典型算法。
1.2算法原理在一给定的无向图G = (V, E) 中, (u, v) 代表连接顶点u 与顶点v 的边(即), 而w(u, v) 代表此边的权重, 若存在T 为E 的子集(即)且为无循环图, 使得的w(T) 最小, 则此T 为G 的最小生成树。
许多应用问题都是一个求无向连通图的最小生成树问题。
例如:要在n个城市之间铺设光缆, 主要目标是要使这n 个城市的任意两个之间都可以通信, 但铺设光缆的费用很高, 且各个城市之间铺设光缆的费用不同;另一个目标是要使铺设光缆的总费用最低。
这就需要找到带权的最小生成树。
1.3算法描述1)最小生成树之普里姆算法描述:令G=(V,E,W), 为简单期间, 令顶点集为V={0,1,2…, n-1}。
假定与顶点i, j相关联的边为ei, j, ei, j的权用c[i][j]表示, T是最小花费生成树的边集。
这个算法维护两个顶点集合S 和N, 开始时: 令T=Ф,S={0},N=V-S。
然后, 进行贪婪选择, 选取i∈S, j∈N, 并且c[i][j]最小的i和j;并使S=S∪S{j},N=N-{j},T=T∪{ei, j}.重复上述步骤, 直到N为空, 或找到n-1条边为止。
此时, T中的边集, 就是所要求取的G中的最小花费生成树。
由此, 可描述普里姆算法的步骤如下:(1)T=Ф, S={0},N=V-S。
(2)如果N为空, 算法结束;否则, 转步骤(3)。
(3)寻找使i∈S, j∈N, 并且c[i][j]最小的i和j。
(4)S=S∪S{j},N=N-{j},T=T∪{ei, j};转步骤(2)。
最小生成树算法及其应用word资料12页
最小生成树算法及其应用1.基础篇1.1定义在电路设计中,常常需要把一些电子元件的插脚用电线连接起来。
如果每根电线连接两个插脚,把所有n个插脚连接起来,只要用n-1根电线就可以了。
在所有的连接方案中,我们通常对电线总长度最小的连接方案感兴趣。
把问题转化为图论模型就是:一个无向连通图G=(V,E),V是插脚的集合,E是插脚两两之间所有可能的连接的集合。
给每条边(u,v)一个权值w(u,v),表示连接它们所需的电线长度。
我们的目标就是找到一个无环的边集T,连接其中所有的点且使总权值最小。
总权值既然T是连接所有点的无环边集,它一定是一棵树。
因为这棵树是从图G 中生成出来的,我们把它叫做生成树。
如果一棵生成树在所有生成树中总权值最小,我们就把它称作最小生成树。
1.2求最小生成树的一般算法解决最小生成树问题有没有一般的方法呢?下面我们就介绍一种贪心算法。
该算法设置了集合A,该集合一直是某最小生成树的子集。
算法执行的每一步,都要决策是否把边(u,v)添加到集合A中,能够添加的条件是保证A∪{(u,v)}仍然是最小生成树的子集。
我们称像(u,v)这样的边为A的安全边,或称这样的边对集合A是安全的。
求最小生成树的一般算法流程如下:GENERIC-MST(G,w)1.A←Ф2.while A没有形成一棵生成树3.do找出A的一条安全边(u,v)4.A←A∪{(u,v)}5.return A一开始A为Ф,显然满足最小生成树子集的条件。
之后,每一次循环都把一条A的安全边加入A中,A依然是最小生成树。
本节的余下部分将提出一条确认安全边的规则(定理1),下一节将具体讨论运用这一规则寻找安全边的两个有效的算法。
图1一个图的割(S,V-S)首先定义几个概念。
有向图G=(V,E)的割(S,V-S)是V的一个分划。
当一条边(u,v)∈E的一个端点属于S而另一端点属于V-S,我们说边(u,v)通过割(S,V-S)。
若集合A中没有边通过割,就说割不妨碍集合A。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验1采用普里姆(prim)算法构造网络的最小生成树
1、实验目的:深入理解虽小生成树的概念,熟练掌握普里姆(prim)算法的工作过程,并通过定
义合适的数据结构,采用C语言程序实现。
2、实验内容:根据模板程序编制普里姆算法的程序,在计算机中进行调试,同时寻找两个结
点大于6的网络,利用文件读入其邻接矩阵,运行程序。
记录运行结果,并把运行结果与手工生成的结果进行比较,验证程序的正解性。
要求从文本文件中读入网络的邻接矩阵。
3、实验原理
①prim算法的主要步骤
②数据表示
③算法实現细节
4、实验步骤与实验结果
①编写prim算法的C语言程序
②输入计算机进行调试
③准备两个顶点大于6的网络,把网络的邻接矩阵输入文本文件中,运行程序,记录程序的运行结果,根据结果画出最小生成树,并与手工生成的最小生成树进行比较。
实验结果:
①画出网络图,写出相应的邻接矩阵
②记录程序的运行结果,根据结果画岀最小生成树并写出最小生成树的权值。
附录:程序模板
# i ncIude <stdio. h>
/*定义一个结构体,用于记录一条边的始点与终点*/
typedef struct pp
{
int p.q;
} edge;
int g[100] [100]. u[100], v[100], vexnum:
edge p[100];//用于记录最小生成树的各条边
void input()〃读入图的邻接矩阵
(
int i. j. temp;
FILE *fp;
fp=fopen("pp5. txt", "r");
fscanf (fp. "%d". &vexnum);
for (i=1 : i <=vexnwn: i ++)
I
printf("\n");
for (j=1; j<=vexniHn: j++)
{
fscanf (fp. "%d". &temp):
g[i] [j]=temp:
pr intf ("%d ", temp):
}
}
fclose(fp);
}
mainO
{
int i. j. k. m. n. ma. s=0;
inputO://输入数据
for (i=1; i<=vexnum; i++)〃集合V中包含了所有顶点
v[i]=1;
u[1]=1:v[1]=0://第1个节点加入至集合U中,并从集合V中去掉
for (i=1; i<=vexnum-1; i++)//最多需vexnum-1 条边
I
//以下找连接节点集U至节点集V的最小边
ma=1000;//ma存放最小边的权值
for (j=1:j<=i:j++)〃集合U中的第j个节点,其编号为u[j].每次增加一个, 共有i个for (k=1;k<=vexnum:k++)
/*v[k]!=0表示节点k在集合V中;g[u[j] [k]>0表示有边*/
if (v[k] !=0&&ma>g[u[j]] [k]&&g[u[j]J [k]>0)
{
ma=g[u[j]][k]:〃保存最小边值m=u[j];//最小边的始点编号n=k://最
小边的终点编号
}
s=s+ma:// 求和
u[i+1]=n;v[n]=0://ffi找到最小边的终点编号从V中去掉,并加入至U中p[i].p=m;
p[i].q=n;//«存最小边的始点编号与终点编号
printf ("\n");
for (i=1;i<=vexnum-1;i++)
printf C\n%d %d %d", p[i]. p. p[i]. q, g[p[i].p] [p[i]. ql): pr i ntf ("\nsum=%d\n\n", s);
实验2采用克鲁斯卡尔(kruskal)算法构造网络的最小生成树
1、实验目的:深入理解最小生成树的概念,熟练掌握克鲁斯E尔(kruskal)算法的工作过程,并
通过定义合适的数据结构.采用C语言程序实现。
2、实验内容:根据模板程序编制克魯斯卡你算法的程序,在计算机中进行调试,同时寻找两
个结点大于6的网络,利用文件读入其邻接矩阵,运行程序。
记录运行结果,并把运行结果与手工生成的结果进行比较,验证程序的正解性。
要求从文本文件中读入网络的邻接矩阵。
3、实验原理
①克鲁斯卡你算法的主要步骤
②数据表示
③算法实現细节
4、实验步骤与实验结果
①编写kruskal算法的C语言程序
②输入计算机进行调试
③准备两个顶点大于6的网络,把网络的邻接矩阵输入文本文件中,运行程序,记录程序的运行结果,根据结果画出最小生成树,并与手工生成的最小生成树进行比较。
实验结果:
①画出网络图,写出相应的邻接矩阵
②记录程序的运行结果,根据结果画出最小生成树并写出最小生成树的权值。
附录:程序模板
# i ncIude <stdio. h>
typedef struct pp//定义最小生成树连的结构
{
int p. q. r ;//顶点1,顶点2,权值
} edge:
int g[100] [100]. sort[100]. vexnum://定义图的邻接矩阵,集合,顶点数edge p[100]. temp; void input()〃读入图的邻接矩阵
{
int i. j. temp;
FILE *fp;
fp=fopenCpp5. txt", "r"):
fscanf (fp. "%d", &vexnum);
for (i=1;i<=vexnum;i++)
I
printf("\n");
for (j=1;j<=vexnum:j++)
{
fscanf (fp. "%d". &temp);
g[i] [j]=temp;
pr intf ("%d temp):
}
}
fclose(fp);
}
ma i n ()
(
int i. j. k. I. m. sum=0;
l=0:
input () ;//从文件读入邻接矩阵
for (i=1:i<=vexnum;i++)〃初始时,每一顶点属于一个集合sort[i]=i;
for (i=1; i<=vexnum-1; i卄)//把边存入p 数组
for (j=i+1;j<=vexnum:j++)
if (g[i][j]>0)
I++;
p[l].p=i:p[l].q=j:p[U. r=g[i] [j]:
1
for (i=1;i<l;i++)//对边按权值进行排序
I
k=i;m=p[k]. r;
for (j=i+1:j<=l;j++)
if (m>p[jj. r)
{
m=p[j]. r;
k=j;
}
temp=p[i];
p[i]=p[k];
p[k]=temp;
k=1;i=1;
whi I e (k<vexnwn)
I
if(sort[p[i].p]!=sort[p[i].q])//同一条边的两个节点分别属于两个集合
{
l=sort[p[i].q]://另一节点的集合号
printf C\n%d %d %d". p[i]. p. p[i]. q. p[i]. r) ://选择这条边
sum=sum+p[i]. r;
for (j=1: j<=vexnum; j++)//把所有集合号为I的节点加于至第一个节点所在的集合中
if (sort[j]=l) sort[j]=sort[p[i]. p]:
k++;
}
pr i ntf ("\nsum=%d\n". sum):。