最小生成树实验报告
最小生成树 实验报告
最小生成树实验报告最小生成树实验报告一、引言最小生成树是图论中的一个重要概念,它在实际问题中有着广泛的应用。
本次实验旨在通过编程实现最小生成树算法,并通过实验数据对算法进行分析和评估。
二、算法介绍最小生成树算法的目标是在给定的带权无向图中找到一棵生成树,使得树上所有边的权重之和最小。
本次实验我们选择了两种经典的最小生成树算法:Prim 算法和Kruskal算法。
1. Prim算法Prim算法是一种贪心算法,它从一个顶点开始,逐步扩展生成树的规模,直到包含所有顶点为止。
算法的具体步骤如下:(1)选择一个起始顶点,将其加入生成树中。
(2)从与生成树相邻的顶点中选择一个权重最小的边,将其加入生成树中。
(3)重复上述步骤,直到生成树包含所有顶点。
2. Kruskal算法Kruskal算法是一种基于并查集的贪心算法,它首先将图中的边按权重从小到大进行排序,然后逐个加入生成树中,直到生成树包含所有顶点为止。
算法的具体步骤如下:(1)将图中的边按权重从小到大进行排序。
(2)逐个加入边,如果该边的两个顶点不在同一个连通分量中,则将其加入生成树中。
(3)重复上述步骤,直到生成树包含所有顶点。
三、实验过程本次实验我们使用C++语言实现了Prim算法和Kruskal算法,并通过随机生成的图数据进行了测试。
1. Prim算法的实现我们首先使用邻接矩阵表示图的结构,然后利用优先队列来选择权重最小的边。
具体实现过程如下:(1)创建一个优先队列,用于存储生成树的候选边。
(2)选择一个起始顶点,将其加入生成树中。
(3)将与生成树相邻的顶点及其边加入优先队列。
(4)从优先队列中选择权重最小的边,将其加入生成树中,并更新优先队列。
(5)重复上述步骤,直到生成树包含所有顶点。
2. Kruskal算法的实现我们使用并查集来维护顶点之间的连通关系,通过排序后的边序列来逐个加入生成树中。
具体实现过程如下:(1)将图中的边按权重从小到大进行排序。
最小生成树 实验报告
最小生成树(Minimum Spanning Tree)实验报告1. 实验目的本实验旨在通过实践掌握最小生成树算法的基本原理和实现方法。
最小生成树是图论中的一个重要概念,用于解决具有权重的连通图的最优路径问题。
通过本实验,我们将学习如何使用最小生成树算法找到一棵连接图的所有节点且总权重最小的树。
2. 实验原理最小生成树是一个连通图的一种生成树,它的所有边的权重之和最小。
最小生成树的求解算法有多种,其中两种常用的算法是 Prim 算法和 Kruskal 算法。
2.1 Prim 算法Prim 算法是一种贪心算法,从一个节点开始,逐步扩展最小生成树的边。
具体步骤如下: 1. 选择一个起始节点作为最小生成树的根节点。
2. 在当前最小生成树的所有节点中选择一个与该树相连接的权重最小的边,将其加入最小生成树。
3. 将该节点标记为已访问。
4. 重复步骤 2 和步骤 3,直到所有节点都被访问。
2.2 Kruskal 算法Kruskal 算法也是一种贪心算法,通过不断选择权重最小的边来构建最小生成树。
具体步骤如下: 1. 对所有边按照权重进行排序。
2. 依次选择权重最小的边,如果该边的两个端点不在同一个连通分量中,则将该边加入最小生成树,并将这两个端点合并到同一个连通分量中。
3. 重复步骤 2,直到所有节点都在同一个连通分量中,即最小生成树构建完成。
3. 实验步骤本实验将使用 Prim 算法和 Kruskal 算法分别求解给定图的最小生成树。
3.1 数据准备首先,我们需要准备一个具有权重的连通图作为实验数据。
假设该图有 n 个节点和 m 条边,我们可以使用邻接矩阵或邻接表来表示这个图。
3.2 Prim 算法求解最小生成树1.首先,选择一个起始节点作为最小生成树的根节点,并将该节点标记为已访问。
2.初始化一个空的最小生成树,用于存储最终的结果。
3.重复以下步骤,直到所有节点都被访问:1.在当前最小生成树的所有节点中选择一个与该树相连接的权重最小的边,将其加入最小生成树。
求最小生成树(Kruskal算法)实验报告
求最小生成树(Kruskal算法)实验报告一、实验目的通过本次实验,掌握Kruskal算法的基本原理,能够使用该算法求解最小生成树问题,并能够进行实际应用。
同时,为学习算法的设计和分析打下基础。
二、实验内容1. 理解Kruskal算法的基本原理。
2. 实现Kruskal算法,并将其应用于求解最小生成树问题。
3. 设计实验测试用例,验证程序正确性并进行性能分析。
三、实验原理Kruskal算法是最小生成树问题的一种解决方法。
该算法基于贪心策略,通过不断选择最短的边来构造最小生成树。
实现步骤如下:1. 将所有边按权重从小到大进行排序。
2. 遍历所有边,每次选择一条没有出现在生成树中的最短边,并将该边所连接的两个顶点合并到同一连通分量中。
3. 直到所有的边都被遍历过,即可得到最小生成树。
四、实验设计本次实验的主要任务是实现Kruskal算法,并运用到最小生成树问题中。
为了测试算法的正确性和性能,需要设计适当的测试用例。
具体的实验步骤如下:1. 设计数据结构在Kruskal算法中,需要维护边的信息,并对边进行排序,同时需要维护顶点的信息。
为方便实现,可以使用C++语言的STL库中的vector和set数据结构。
vector用于存储顶点信息,set用于存储排序后的边信息。
其中,顶点包含顶点编号和连通分量编号,边包含起点、终点和边权重。
为了方便生成测试数据,定义两个常量:MAX_VERTEX和MAX_EDGE。
MAX_VERTEX表示最大顶点数量,MAX_EDGE表示最大边数量。
2. 生成测试数据为了测试算法的正确性和性能,需要生成不同大小的测试数据。
可以随机生成若干个顶点和相应的边,其中顶点编号从1开始连续编号,边的起点和终点使用随机数生成,边的权重也使用随机数生成。
3. 实现Kruskal算法根据算法原理,可以实现基本的Kruskal算法。
具体实现过程如下:1. 首先将所有的边按照权重从小到大排序,并分别初始化每个顶点的连通分量编号。
Prim最小生成树 实验报告含源码
实验报告题目说明:POJ2395 Out of Ray题目大意:Beth有m个农场,农场之间有些相通,有些不通。
已知,Beth每一英里要一盎司的水,Beth希望走遍所有的农场但携带最少的水。
问:Beth最多需要带多少水?(每个农场都可以补充水)本程序利用Prim算法俩实现题目要求。
1.<创建>输入农场数和农场之间的距离(均为整数),程序给出连通判断。
2.修改路径按格式输入修改值,此时路线可能会改变。
3.<输出最大携带水量>,附上最小生成树实验说明:1.基本思想利用邻接表G [ ][ ] 储存农场信息,然后使用Prim算法来完成最小生成树的构建;最后寻找出最大边,如果农场是不连通的将给出提示,可以对路径修改。
2.函数模块(1)int InitiTable(int G[][MaxFarm],int num);//创建邻接表,返回值是农场数目{int j,k,TempValue;while(true){cout<<"请输入农场的数目:"<<' ';cin>>num;if(num<=MaxFarm&&num>0)break;cout<<"错误!请重新输入."<<endl<<endl;}for(j=0;j<num;j++){for(k=0;k<num;k++){if(j==k)G[j][k]=MaxWeight;else if(j<k){while(true){cout<<"请输入农场"<<j+1<<"至农场"<<k+1<<"的距离。
如果该路不存在请输入-1:"<<endl;cin>>TempValue;if(TempValue>=-1&&TempValue<MaxWeight) break;cout<<"输入无效,请重新输入。
最小生成树算法实验报告
最小生成树算法实验报告【实验报告】最小生成树算法实验一、实验目的本次实验旨在研究最小生成树算法,通过对比不同的算法,并对实验结果进行分析,探索最小生成树算法的优劣势和适应场景。
二、实验过程1.算法介绍本次实验中我们将使用两种最小生成树算法:普里姆算法和克鲁斯卡尔算法。
- 普里姆算法(Prim算法):从一个顶点开始,不断在剩下的顶点中选择到当前已有的最小生成树的距离最小的边,将该边的另一个顶点加入树中,直到所有的顶点都加入树中。
- 克鲁斯卡尔算法(Kruskal算法):首先将所有边按照权值从小到大进行排序,然后以最小权值的边开始,依次选择权值最小且不会形成环路的边,直到找到n-1条边为止,其中n为顶点数。
2.实验步骤首先,我们使用Python语言实现了普里姆算法和克鲁斯卡尔算法。
然后,我们构造了一些测试用例,包括不同规模的图和不同权值分布的图。
最后,我们对实验结果进行对比分析。
三、实验结果1.测试用例设计我们设计了三个测试用例,分别为小规模图、中规模图和大规模图,具体如下:-小规模图:顶点数为5的图,权值随机分布。
-中规模图:顶点数为50的图,权值随机分布。
-大规模图:顶点数为100的图,权值随机分布。
2.实验结果分析我们的实验结果如下表所示:算法,小规模图,中规模图,大规模图:-------:,:------:,:------:,:------:普里姆算法,13,455,703从实验结果可以看出,对于小规模图和中规模图,普里姆算法的运行时间明显低于克鲁斯卡尔算法。
但是对于大规模图,克鲁斯卡尔算法的运行时间与普里姆算法的运行时间差距不大,甚至略小于普里姆算法。
这是因为克鲁斯卡尔算法中排序边的时间复杂度为O(ElogE),而普里姆算法中筛选最小距离的边的时间复杂度为O(V^2)。
综上所述,普里姆算法适用于较小规模的图,而克鲁斯卡尔算法适用于较大规模的图。
四、实验总结本次实验研究了最小生成树算法,通过对比实验结果,我们发现不同算法在不同规模的图上的表现有所差异。
最小生成树算法实验报告
最小生成树算法问题描述设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(I)for i:=2 to n do⑵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(II)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循环都要0(n)时间,所以Prim算法所需的计算时间为O(n2 )。
实验5最小生成树算法的设计与实现(报告)
实验5 最小生成树算法的设计与实现一、实验目的1、根据算法设计需要, 掌握连通图的灵活表示方法;2、掌握最小生成树算法,如Prim、Kruskal算法;3、基本掌握贪心算法的一般设计方法;4、进一步掌握集合的表示与操作算法的应用。
二、实验内容1、认真阅读算法设计教材和数据结构教材内容, 熟习连通图的不同表示方法和最小生成树算法;2、设计Kruskal算法实验程序。
有n个城市可以用(n-1)条路将它们连通,求最小总路程的和。
设计测试问题,修改并调试程序, 输出最小生成树的各条边, 直至正确为止。
三、Kruskal算法的原理方法边权排序:1 3 14 6 23 6 41 4 52 3 53 4 52 5 61 2 63 5 65 6 61. 初始化时:属于最小生成树的顶点U={}不属于最小生成树的顶点V={1,2,3,4,5,6}2. 根据边权排序,选出还没有连接并且权最小的边(1 3 1),属于最小生成树的顶点U={1,3},不属于最小生成树的顶点V={2,4,5,6}3. 根据边权排序,选出还没有连接并且权最小的边(4 6 2),属于最小生成树的顶点U={{1,3},{4,6}}(还没有合在一起,有两颗子树),不属于最小生成树的顶点V={2,5}4. 根据边权排序,选出还没有连接并且权最小的边(3 6 4),属于最小生成树的顶点U={1,3,4,6}(合在一起),不属于最小生成树的顶点V={2,5}5. 根据边权排序,选出还没有连接并且权最小的边(3 6 4),属于最小生成树的顶点U={1,2,3,4,6},,不属于最小生成树的顶点V={5}6. 根据边权排序,选出还没有连接并且权最小的边(3 6 4),属于最小生成树的顶点U={1,2,3,4,5,6}此时,最小生成树已完成四、实验程序的功能模块功能模块:bool cmp(Edge a,Edge b); //定义比较方法x);//在并查集森林中找到x的祖先int g etfa(intint s ame(int x,int y); //判断祖先是否是同一个,即是否联通 void merge(int x,int y); //合并子树,即联通两子树sort(e+1,e+m+1,cmp); //对边按边权进行升序排序详细代码:#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define M AXN_E 100000#define M AXN_V 100000using namespace std;struct Edge{int f m,to,dist;//边的起始顶点,边的到达顶点,边权}e[MAXN_E];int f a[MAXN_V],n,m; //顶点数组,顶点总数,边总数 //定义比较,只是边权比较bool cmp(Edge a,Edge b){return a.dist < b.dist;}//查找x的祖先是在并查集森林中找到x的祖先x){//getfaint g etfa(intreturn fa[x];if(fa[x]==x)else r eturn fa[x] = getfa(fa[x]);}//判断祖先是否是同一个,即是否联通int s ame(int x,int y){return getfa(x)==getfa(y);}//合并两棵树void merge(int x,int y){int f ax=getfa(x),fay=getfa(y);fa[fax]=fay;}int m ain(){int i;cout<<"请输入顶点数目和边数目:"<<endl;cin>>n>>m;//n为点数,m为边数//输出顶点信息cout<<"各个顶点值依次为:"<<endl;for(i=0;i<n;i++){fa[i]=i;if(i!=0)cout<<fa[i]<<" ";}cout<<endl;cout<<"请输入边的信息(例子:1 4 5 从顶点1到顶点4的边权为5)"<<endl;for(i=1;i<=m;i++)用边集数组存放边,方便排序和调用 cin>>e[i].fm>>e[i].to>>e[i].dist;//sort(e+1,e+m+1,cmp); //对边按边权进行升序排序表示目前的点共存在于多少个集合中,初始情况是每 int r st=n,ans=0;//rst个点都在不同的集合中for(i=1;i<=m && rst>1;i++){int x=e[i].fm,y=e[i].to;函数是查询两个点是否在同一集合中 if(same(x,y))continue;//sameelse{函数用来将两个点合并到同一集合中 merge(x,y);//mergerst--;//每次将两个不同集合中的点合并,都将使rst值减1这条边是最小生成树中的边,将答案加上边权 ans+=e[i].dist;//}}cout<<ans;return 0;}五、测试数据和相应的最小生成树Input:6 101 2 61 3 11 4 52 3 52 5 63 4 53 5 63 6 44 6 25 6 6Putout:18生成树为:七、思考题1、微软面试题一个大院子里住了50户人家,每家都养了一条狗,有一天他们接到通知说院子里有狗生病了,并要求所有主人在发现自己家狗生病的当天就要把狗枪杀掉。
数据结构实验报告-最小生成树(精选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++语言集成开发环境。
数据结构实验报告最小生成树
数据结构实验报告最小生成树实验目的:掌握最小生成树的概念和算法,培养分析和解决实际问题的能力。
实验内容:利用Kruskal算法求解带权无向连通图的最小生成树。
实验原理:最小生成树是指一个连通图的生成树,其中所有边的权值和最小。
最小生成树问题在图论中有着重要的应用,如网络设计、集成电路布线等领域。
本次实验使用Kruskal算法求解最小生成树。
Kruskal算法基于一个贪心的思想:每次选择权值最小的边,直到生成树中包含所有的节点。
具体算法如下:1.根据给定的连通图构造一个边的集合E,E中包含图中所有的边。
2.将E中的边按照权值从小到大排序。
3.依次遍历排序后的边,如果该边的两个节点不在同一个连通分量中,则选择该边,并将这两个节点合并到一个连通分量中。
4.重复第3步,直到生成树中包含所有的节点。
实验步骤及结果:1.根据给定的连通图构造边的集合E,并将E中的边按照权值从小到大排序。
2.初始化一个空的集合T作为最小生成树的边集合。
3.依次遍历排序后的边,如果该边的两个节点不在同一个连通分量中,则选择该边,并将这两个节点合并到一个连通分量中,同时将该边添加到集合T中。
4.重复第3步,直到生成树中包含所有的节点。
实验结果分析:通过Kruskal算法,可以得到带权无向连通图的最小生成树。
最小生成树具有多个优点,如能够保证连通、权值最小、无回路。
在实际应用中,最小生成树常常用于网络设计、集成电路布线等领域。
实验总结:通过本次实验,我掌握了最小生成树的概念和Kruskal算法的原理和实现方法。
实验中,我通过定义边的数据结构和构造边的集合,实现了Kruskal算法求解最小生成树。
通过实验,我深刻认识到数据结构在解决实际问题中的重要性和实用性。
最小生成树作为一种常用的图论算法,在实际应用中具有广泛的应用和重要的价值。
掌握了最小生成树的概念和算法,我相信能够在今后的学习和工作中更好地应用数据结构算法解决实际问题。
数据结构实验Prim最小生成树
实验三:Prim 最小生成树(验证性、4学时)一、 实验目的和要求●理解图的遍历●理解构造无向联通图的最小生成树的方法(Prim 算法实现)●能用Prim 算法构造最小生成树出来二、 实验内容和原理(1)实验内容:用Prim 算法构造一颗最小生成树(2) 实验原理:①从网中任一顶点开始,先把该顶点包含在生成树中,此时生成树只有一个顶点。
②找出一个端点在生成树中另一端点在生成树外的所有边,并把权值最小的边连到同它所关联的另一个顶点添加到生成树中;当有两条及以上具有相同最小权值的边可供选择时,任选一条。
③反复执行②,直到所有顶点都包含在生成树时为止。
三、 实验环境硬件:(1)学生用微机(2)多媒体教室或远程教学(3)局域网环境软件:(1)Windows XP 中文操作系统 (2)Turbo C 3.0四、 算法描述及实验步骤1、算法描述为了实现Prim 算法。
需设一个辅助数组closedge 来记录每次选择的权值最小的边。
数组元素closedge[i]对应于序号为i 的顶点v i ,它包含两个域adjvex 和lowcost 。
若v i 已在生成树上,则置closedge[i].lowcost=0;若顶点v i 不在生成树上,用closedge[i].low cost 存放v i 与生成树上的顶点构成的最小代价边的权值,而用closedge[i].adjvex 存放该边所关联的生成树上的另一顶点的序号。
2、算法流程图begin typedef struct ArcCellvoid CreateGraph(MGraph &G) hand !=110 1113、代码(注释)#include <stdio.h>#include <stdlib.h>#include <iostream.h>#define INFINITY INT_MAX tide != G .vexs[k] G .arcs[j][k].adj = weigh; G .arcs[k][j].adj = weigh; j = 0;k = 0;void MiniSpanTree_PRIM(MGraph G ,V erTexType u) j<G .vexnum G .arcs[k][j].adj < close[j].lowcostclose[j].adjvex = G .vexs[k]; close[j].lowcost= G .arcs[k][j].adj;j++ j++j=0i++int LocateV ex(MGraph G , V erTexType u) end int minimum(closedgeclose)#define MAX_VERTEX_NUM 20 //最大顶点数为20//typedef int VRType;typedef int InfoType;typedef char V erTexType;typedef struct ArcCell // 邻接矩阵定义//{VRType adj;InfoType *info; }ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; typedef struct{V erTexType vexs[MAX_VERTEX_NUM];AdjMatrix arcs;int vexnum, arcnum; }MGraph;typedef struct //记录从顶点集U到V-U的代价最小的边的辅助数组定义//{ V erTexType adjvex;VRType lowcost;}closedge[MAX_VERTEX_NUM];void CreateGraph(MGraph &G); //建立无向图//void MiniSpanTree_PRIM(MGraph G, V erTexType u);//用Prim算法从第u个顶点出发构造无向连通网G的最小生成树T//int LocateV ex(MGraph G, V erTexType u);//求顶点在图中的位置//int minimum(closedge close);//最小边的权重//void main( void ){int i, j;MGraph G;cout<<"==================用Prim算法求最小生成树==================="<<endl; CreateGraph(G);//调用CreateGraph(G)建立图//cout<<"程序所建立的图的邻接矩阵如下所示:"<<endl;cout<<"-------------------------------------";cout<<endl<<" ";for(i = 0; i < G.vexnum; i++){cout<<G.vexs[i]<<" ";}cout<<endl;for(i = 0; i < G.vexnum; i++){cout<<G.vexs[i]<<" ";for(j = 0; j < G.vexnum; j++){cout<<G.arcs[i][j].adj;cout<<" ";}cout<<endl;}cout<<"-------------------------------------"<<endl;MiniSpanTree_PRIM(G,'a');}void CreateGraph(MGraph &G)//构造无向连通网G//{int weigh;//weigh变量为图中结点的权重//int i, j = 0, k = 0;char hand, tide;cout<<"请您输入所建图中的结点的个数the number for vexnum:";cin>>G.vexnum;cout<<"请您输入所建图中的各结点间的连接的边数(最大边数为"<<G.vexnum*G.vexnum<<")the number for arcnum:";cin>>G.arcnum;for(i = 0; i < G.vexnum; i++){for(j = 0; j < G.vexnum; j++)G.arcs[i][j].adj = 99; }//图中两个结点不相联,权值定为99//cout<<endl;cout<<"请您输入"<<G.vexnum<<"(char)型的字符作为图中的结点名称:"<<endl;for(i=0; i < G.vexnum; i++){cin>>G.vexs[i];}cout<<endl;cout<<"请您输入"<<G.vexnum<<"(char)型的字符作为图中的结点名称:"<<endl;for(i=0; i < G.arcnum; i++){cout<<i+1<<":";cin>>hand;cin>>tide;cin>>weigh;while (hand != G.vexs[j]){j++;}while (tide != G.vexs[k]){k++;}G.arcs[j][k].adj = weigh;G.arcs[k][j].adj = weigh;j = 0;k = 0;}cout<<endl;}void MiniSpanTree_PRIM(MGraph G,V erTexType u)//用Prim算法从第u个顶点出发构造网G 的最小生成树T,输出它的各条边并算出//{int i, j, k = 0;closedge close;k = LocateV ex ( G, u );for ( j = 0; j < G.vexnum; j++ )//辅助数组初始化//{if (j != k){close[j].adjvex = G.vexs[k];close[j].lowcost = G.arcs[k][j].adj;}}close[j].lowcost = 99;close[j].adjvex = '\0';close[k].lowcost = 0;close[k].adjvex = u;cout<<"用Prim算法实现的程序求得的最小生成树如下所示:"<<endl;for (i = 1; i < G.vexnum; i++)//选择其余G.vexnum-1个顶点//{k = minimum(close); //求出T的下一个结点:第k个顶点//cout<<close[k].adjvex; //输出生成树的边//cout<<"---->";cout<<G.vexs[k]<<" ";cout<<close[k].lowcost<<endl;close[k].lowcost = 0; //第k顶点并入U集//for (j=0; j<G.vexnum; j++){if (G.arcs[k][j].adj < close[j].lowcost)//新顶点并入U集后重新选择最小边//{close[j].adjvex = G.vexs[k];close[j].lowcost = G.arcs[k][j].adj;} } } }int LocateV ex(MGraph G, V erTexType u)//求顶点在图中的位置//{int k = 0;while(G.vexs[k++] == u)return k-1;return 0;}//若G中存在顶点u则返回该顶点在图中的位置,否则返回-1//int minimum(closedge close)//最小边的权重//{int j1=0, client = 99, j2;while(close[j1].adjvex != '\0'){if (client > close[j1].lowcost && close[j1].lowcost != 0){client = close[j1].lowcost;j2 = j1;}j1++;}return j2;}五、调试过程出错原因:语句“InfoType ->info;”出错,只要把“InfoType ->info;”改为即“InfoType *info;”即可。
数据结构实验最小生成树
数据结构实验最小生成树数据结构实验报告最小生成树问题一、问题描述:若要在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. 掌握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函数找出当前端点所在集合编号。
最小生成树实验报告
最小生成树实验报告1.引言最小生成树(Minimum Spanning Tree,简称MST)是图论中的重要概念,在各个领域都有广泛的应用。
最小生成树是指在给定的加权连通图中,选择一个子集,使得该子集包含了所有的顶点,并且所有边的权值之和最小。
本实验主要目的是探讨最小生成树的算法并比较它们的效率和准确性。
2.实验方法本次实验使用Python编程语言实现了两种著名的最小生成树算法:Prim算法和Kruskal算法。
Prim算法是一种贪心算法,从一个顶点开始不断扩张集合,直到包含所有顶点,生成最小生成树。
Kruskal算法则是基于并查集的算法,将边按照权值排序后逐一加入生成树,同时要保证加入的边不会产生环路。
3.实验过程首先,我们从文件中读取了一张加权无向图的数据。
图的表示采用邻接矩阵的方式,即用一个二维数组来存储顶点之间的连接关系和权值。
读取完图的数据后,我们分别使用Prim算法和Kruskal算法求解最小生成树。
在Prim算法中,我们使用一个辅助数组来记录顶点是否已被访问过,然后从任意一个顶点开始,依次将与当前集合相邻的顶点加入,并选择权值最小的边。
直到所有顶点都被访问过,并形成了一个最小生成树。
在Kruskal算法中,我们首先将所有边按照权值从小到大进行排序。
然后,从权值最小的边开始,逐一将边加入生成树。
加入时,需要判断两个顶点是否在同一个连通分量中,以避免产生环路。
实验中,我们使用了Python中的heapq库来实现了堆排序,以加快Prim算法的运行速度。
4.实验结果经过实验,我们得到了图的最小生成树以及对应的权值。
实验数据显示,当图中顶点较少时,Prim算法和Kruskal算法几乎没有明显的差别。
但当图的规模增大时,Prim算法明显比Kruskal算法更快。
5.实验分析从实验结果可以看出,Prim算法和Kruskal算法都可以求解最小生成树,但在不同情况下它们的性能表现并不相同。
Prim算法适用于稠密图,因为它的时间复杂度与顶点的平方成正比;而Kruskal算法适用于稀疏图,因为它的时间复杂度与边的数量成正比。
最小生成树实验报告
最小生成树实验报告最小生成树(Minimum Spanning Tree,MST)是图论中的一个重要概念,用于在一个连通带权无向图中找到一个子图,使得这个子图是一个树(即无环连通图),并且所有边的权值之和最小。
最小生成树在诸多领域有着广泛的应用,如网络设计、电力传输等。
在本次实验中,我们实现了最小生成树算法,并将其运用到多个实际问题上。
下面将依次介绍算法原理、实现过程、实验结果以及对实验的进一步改进。
1.算法原理Kruskal算法的基本思想是,首先将所有边按照权值从小到大排序,然后从最小的边开始,逐一加入生成树,直到生成树包含了所有的顶点。
在加入一条边时,需要判断这条边将两个顶点连通起来是否会形成环,如果不会则加入生成树。
Prim算法的基本思想是,从一个顶点开始,逐步加入生成树的顶点,每次加入一个顶点时,选择一个离生成树最近的点,并将这个点加入生成树。
通过不断的选择顶点和加入边,最终得到最小生成树。
2.实现过程首先,我们实现了图的数据结构和边的数据结构。
在图的数据结构中,我们定义了图的顶点数和边数,并用邻接矩阵来表示图的连接情况。
边的数据结构包含了两个顶点和边的权值。
其次,我们实现了两种算法。
对于Kruskal算法,我们首先将所有边按照权值从小到大进行排序。
然后,逐个加入边,判断是否形成环。
如果不会形成环,则将该边加入生成树。
最后,我们使用并查集数据结构来判断两个顶点是否连通。
对于Prim算法,我们首先选择一个起点作为生成树的初始顶点,并将其加入生成树。
然后,每次选择一个离生成树最近的顶点,并将其加入生成树,同时更新其他顶点到生成树的距离。
最后,所有顶点都被加入生成树后,得到最小生成树。
3.实验结果我们在实验中选择了不同大小的图进行测试。
经过对比,我们发现Kruskal算法和Prim算法得到的最小生成树结果是一致的,但是Kruskal 算法的时间复杂度要稍高于Prim算法。
具体的结果如下:对于一个边数为10的图,我们得到了如下最小生成树:1-2-4-5-3总权重为12对于一个边数为20的图,我们得到了如下最小生成树:2-1-4-5-3总权重为16对于一个边数为30的图2-1-4-5-6-7-3总权重为22从实验结果来看,无论是规模较小的图还是规模较大的图,我们都能够得到最小生成树,并且所得到的结果是正确的。
c++最小生成树设计报告
实验四最小生成树题目:建立图并求出最小生成树班级:计科0906 姓名:马飞扬学号:200948140622 完成日期:一:需求分析根据输入的城市结点个数,建立图型存储结构,并在该图中求出最小生成树,输出组成它的结点以及对应的边上的权值。
二:概要设计1:用户输入结点个数后,为各个结点通过循环进行命名。
让客户输入各边对应的权值,共需循环n*(n-1)/2次。
由输入的信息,建立对应的图型存储结构。
2:建立一个辅助数组来存储各个结点对应连入当前的生成树所通过的结点以及连入当前生成树对应的最小权值。
通过n-1次循环,每次找到一个结点,连入当前的生成树中。
找到一个结点后将其标志为已找到,并修改其他结点对应的连入信息,看看其他结点若通过刚找到的结点连入到生成树中是否会路径更短,如果是则修改为通过新节点连入,若不是则不修改。
这样,最终把所有结点都连入到了生成树中,生成树也讲究建成了。
三:详细设计#include<iostream>#define maxnum 1000000#define maxn 26using namespace std;int creatgraph(int n);//声明创建图的函数void creatmintree(int state);//声明创建最小生成树函数struct graph//定义图的存储结构{char vexs[maxn+2];int arcs[maxn+1][maxn+1];int vexnum;int arcnum;};struct fuzhuarray//定义辅助数组结构{int adjvex;int lowcost;};graph graph1;//定义图变量fuzhuarray closedge[maxn+1];//定义辅助数组void main(){int state=0;int n=0;cout<<"输入城市个数(3~26):";cin>>n;state=creatgraph(n);//state记录建立的图的边数cout<<"最小生成树为:";creatmintree(state);//据state来判断是否有必要创建最小生成树}int creatgraph(int n){int i=0;int j=0;int m=0;int s=0;int ss=0;if(n>=3)//输入结点大于3时创建图才有意义{for(i=1;i<=n;i++)//为图的各个结点名称赋值{graph1.vexs[i]=char(64+i);}graph1.vexs[n+1]='\0';cout<<"输入各边权值(未知输入-1):"<<endl;for(i=1;i<n;i++)//循环n*(n-1)/2次为图的邻接矩阵赋值{graph1.arcs[i][i]=0;for(j=i+1;j<=n;j++){cout<<""<<char(64+i)<<"到"<<char(64+j)<<"的费用:";cin>>s;if(s!=-1){graph1.arcs[i][j]=s;ss++;}else{graph1.arcs[i][j]=maxnum;}graph1.arcs[j][i]=graph1.arcs[i][j];//无向图的邻接矩阵对称,可对称赋值}}graph1.vexnum=n;//记录图的节点数graph1.arcnum=ss;//记录图的边数}else{cout<<"城市过少无意义!"<<endl;}return ss;//返回边数}void creatmintree(int state){if(state>=graph1.vexnum-1){int k=1;//初始化从第一个结点开始建立生成树int kk=0;for(int i=1;i<=graph1.vexnum;i++)//辅助数组初始化{if(i!=k){closedge[i].adjvex=1;closedge[i].lowcost=graph1.arcs[k][i];}}closedge[k].lowcost=0;for(int j=1;j<graph1.vexnum;j++)//循环找到剩余的n-1个生成树的结点{kk=maxnum;for(i=2;i<=graph1.vexnum;i++)//找到当前最小权值{if(closedge[i].lowcost!=0){kk=(kk<closedge[i].lowcost)?kk:closedge[i].lowcost;}}for(i=2;i<=graph1.vexnum;i++)//定位最小权值所在的结点位置{if(closedge[i].lowcost==kk){k=i;break;}}cout<<"<"<<graph1.vexs[closedge[k].adjvex]<<","<<graph1.vexs[k]<<">"<<"权值为:"<<graph1.arcs[closedge[k].adjvex][k]<<" ";//输出信息closedge[k].lowcost=0;//标志该结点已被找到for(int m=2;m<=graph1.vexnum;m++)//对其他节点的连入结点及最小连入权值进行修改{if(graph1.arcs[k][m]<closedge[m].lowcost){closedge[m].adjvex=k;closedge[m].lowcost=graph1.arcs[k][m];}}}cout<<endl;}else{cout<<"输入错误!"<<endl;}}四:调试分析在建立图的过程中,题目要求是输入结点个数以及边数,然后输入各边权值。
最小生成树prim算法实验报告
最小生成树prim算法实验报告最小生成树Prim算法实验报告引言:最小生成树(Minimum Spanning Tree,简称MST)是图论中的一个重要概念,意为在一个连通图中找到一棵生成树,使得树上所有边的权值之和最小。
Prim算法是一种常用的解决MST问题的贪心算法。
本实验旨在通过实际操作和观察,深入理解Prim算法的原理与过程。
实验目的:1. 理解Prim算法的基本原理;2. 掌握Prim算法的具体实现过程;3. 利用Prim算法求解最小生成树问题;4. 分析Prim算法的时间复杂度。
实验过程:1. 实验环境搭建:在实验开始前,我们需要搭建合适的实验环境。
首先,我们选择一种编程语言,如Python或C++,来实现Prim算法。
其次,我们需要准备一个图的数据集,可以是随机生成的或者是从现实问题中提取的。
最后,我们需要一个用于可视化的工具,以便观察Prim算法的执行过程和结果。
2. Prim算法实现:Prim算法的核心思想是从一个顶点开始,逐步扩展生成树,直到包含所有顶点为止。
具体实现过程如下:a. 初始化一个空的生成树,选择一个起始顶点;b. 在剩余的顶点中,选择与生成树距离最近的顶点,并将其加入生成树;c. 更新生成树与剩余顶点的距离,如果存在更短的路径,则更新;d. 重复步骤b和c,直到生成树包含所有顶点。
3. Prim算法求解最小生成树问题:利用Prim算法求解最小生成树问题的步骤如下:a. 根据实验环境搭建中准备的图数据集,构建图的邻接矩阵或邻接表表示;b. 选择一个起始顶点,将其加入生成树;c. 重复以下步骤,直到生成树包含所有顶点:i. 从生成树中选择一个顶点v,找到与v相连的顶点中距离最小的顶点u; ii. 将顶点u加入生成树,并将(u, v)边加入生成树的边集;iii. 更新生成树与剩余顶点的距离,如果存在更短的路径,则更新。
实验结果与分析:我们通过实验环境搭建和Prim算法实现,成功求解了多个最小生成树问题。
PRIM算法实验报告
篇一:prim算法实验报告算法实验报告学院:xxx班级:xxx学号:xxx姓名:xxx prim篇二:prim最小生成树算法实验报告算法分析与设计之prim学院:软件学院学号:201421031059 姓名:吕吕一、问题描述1. prim的定义prim算法是贪心算法的一个实例,用于找出一个有权重连通图中的最小生成树,即:具有最小权重且连接到所有结点的树。
(强调的是树,树是没有回路的)。
2. 实验目的选择一门编程语言,根据prim算法实现最小生成树,并打印最小生成树权值。
二、算法分析与设计1.prim算法的实现过程基本思想:假设g=(v,e)是连通的,te是g上最小生成树中边的集合。
算法从u={u0}(u0∈v)、te={}开始。
重复执行下列操作:在所有u∈u,v∈v-u的边(u,v)∈e中找一条权值最小的边(u0,v0)并入集合te中,同时v0并入u,直到v=u为止。
此时,te中必有n-1条边,t=(v,te)为g的最小生成树。
prim算法的核心:始终保持te中的边集构成一棵生成树。
2.时间复杂度prim算法适合稠密图,其时间复杂度为o(n^2),其时间复杂度与边得数目无关,n为顶点数,而看ruskal算法的时间复杂度为o(eloge)跟边的数目有关,适合稀疏图。
三、数据结构的设计图采用类存储,定义如下:class graph{private:int *verticeslist; int **edge; int numvertices; int numedges; int maxvertices; graph(); ~graph(); bool insertvertex(const int vertex); bool insertedge(int v1,int v2,int cost); int getvertexpos(int vertex); int getvalue(int i); int getweight(int v1,int v2); int numberofvertices();1public:} void prim();其中,图中结点连接情况及权值使用二重指针表示,即二维数组实现邻接矩阵。
最小生成树算法实验报告_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)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构课程设计报告题目:最小生成树问题
院(系):计算机工程学院
学生姓名:
班级:学号:
起迄日期:
指导教师:
2011—2012年度第 2 学期
一、需求分析
1.问题描述:
在n个城市之间建设网络,只需保证连通即可,求最经济的架设方法。
存储结构采用多种。
求解算法多种。
2.基本功能
在n个城市之间建设网络,只需要架设n-1条线路,建立最小生成树即可实现最经济的架设方法。
程序可利用克鲁斯卡尔算法或prim算法生成最小生成树。
3.输入输出
以文本形式输出最小生成树,同时输出它们的权值。
通过人机对话方式即用户通过自行选择命令来输入数据和生成相应的数据结果。
二、概要设计
1.设计思路:
因为是最小生成树问题,所以采用了课本上介绍过的克鲁斯卡尔算法和 prim算法两种方法来生成最小生成树。
根据要求,需采用多种存储结构,所以我选择采用了邻接表和邻接矩阵两种存储结构。
2.数据结构设计:
图状结构:
ADT Graph{
数据对象V:V是具有相同特性的数据元素的集合,称为顶点集。
数据关系R:R={VR}
VR={<v,w>|v,w∈V且P(v,w),<v,w>表示从v到w的弧,
谓词P(v,w)定义了弧<v,w>的意义或信息}
基本操作:
CreateGraph( &G, V, VR )
初始条件:V是图的顶点集,VR是图中弧的集合。
操作结果:按V和VR的定义构造图G。
DestroyGraph( &G )
初始条件:图G存在。
操作结果:销毁图G。
LocateVex( G, u )
初始条件:图G存在,u和G中顶点有相同特征。
操作结果:若G中存在顶点u,则返回该顶点在图中位置;否则返
回其它信息。
GetVex( G, v )
初始条件:图G存在,v是G中某个顶点。
操作结果:返回v的值。
PutVex( &G, v, value )
初始条件:图G存在,v是G中某个顶点。
操作结果:对v赋值value。
FirstAdjVex( G, v )
初始条件:图G存在,v是G中某个顶点。
操作结果:返回v的第一个邻接顶点。
若顶点在G中没有邻接顶点,
则返回“空”。
NextAdjVex( G, v, w )
初始条件:图G存在,v是G中某个顶点,w是v的邻接顶点。
操作结果:返回v的(相对于w的)下一个邻接顶点。
若w是v的
最后一个邻接点,则返回“空”。
InsertVex( &G, v )
初始条件:图G存在,v和图中顶点有相同特征。
操作结果:在图G中增添新顶点v。
DeleteVex( &G, v )
初始条件:图G存在,v是G中某个顶点。
操作结果:删除G中顶点v及其相关的弧。
InsertArc( &G, v, w )
初始条件:图G存在,v和w是G中两个顶点。
操作结果:在G中增添弧<v,w>,若G是无向的,则还增添对称弧 <v,w>。
DeleteArc( &G, v, w )
初始条件:图G存在,v和w是G中两个顶点。
操作结果:在G中删除弧<v,w>,若G是无向的,则还删除对称弧 <v,w>。
DFSTraverse( G, Visit() )
初始条件:图G存在,Visit是顶点的应用函数。
操作结果:对图进行深度优先遍历。
在遍历过程中对每个顶点调用
函数Visit一次且仅一次。
一旦visit()失败,则操作失败。
BFSTraverse( G, Visit() )
初始条件:图G存在,Visit是顶点的应用函数。
操作结果:对图进行广度优先遍历。
在遍历过程中对每个顶点调用
函数Visit一次且仅一次。
一旦visit()失败,则操作失败。
}ADT Graph
存储结构:
邻接矩阵:
#define INFINITY INT_MAX据类型的定义
<1>图类型
#define M 20
#define MAX 20
#define null 0
#define MAX_VERTEX_NUM 20要模块的算法描述
<1>主函数
int main(void) owcost=0; egin;
把j赋给edges[k].end;
把i,j之间的权值赋给edges[k].weight;
K++;}/*对结构体edge进行初始化*/
}
}
对图G边的权值进行排序sort(edges, G);
当循环变量i小于当前弧度数时
{将0赋给parent[i],初始化数组;}
当循环变量i小于当前弧度数时(此时第i条弧为最小的) {
找第i条弧的起点和终点;并分别赋给你n,m;
当n,m不相等时
{把m赋给parent[n];
输出此时第i条弧的起点、终点、权值;
}
}
}
流程图:
四、调试分析
本次课程设计基本达到了设计需求。
但是还有很多不足。
比如不能随意切换两种算法,也不能由用户选择使用邻接矩阵还是邻接表,以后更加深入的学习计算机知识或许可以在这两个方面进行改进。
五、测试结果
prim算法正确结果:
prim算法错误结果:
克鲁斯卡尔算法正确结果:
克鲁斯卡尔算法错误结果:
六、体会与自我评价
“数据结构”是计算机程序设计的重要理论技术基础,它不仅是计算机学科的核心课程,而且已成为其他理工专业的热门选修课。
本学期通过学习这门课程,我学会了分析研究计算机加工的数据结构的特性,以及算法的事件分析和空间分析。
这些帮助我在设计程序的过程中,更好为数据选择适当的逻辑结构、存储结
构及其相应的算法。
通常情况下,交通、道路问题的数学模型是一种称为“图”的数据结构。
在本课题中,每个顶点代表一个城市,每一条边代表一条通信录井,同时给每条路径赋予权值,代表着这条路径的建设代价。
通过最小生成树的实现,可以实现以最节省经费的方式来建立这个通信网。
对于n个顶点的联通网可以建立许多不同的生成树,每一棵生成树都可以是一个通信网。
但是根据要求,我们需要以最少的经费来完成整个通信网的建设,于是便有了最小生成树问题。
为了完成本次课程设计,因为课本上只有prim算法的代码,所以克鲁斯卡尔算法还需要自己使用百度进行查找。
在查找到算法之后,要将其变为程序源代码,将它们的功能实现出来。
这就需要用到计算机高级语言编程了。
我们所学的是C语言版的数据结构,C语言的课程是在大一下半学期就完成的,所以总体来说难度并不是很大。
再加上题目要求也不多,属于很简单的题目,所以基本上没有碰到大的难题。
通过本次设计,我对C语言有了更深一层的认识,同时也更好的掌握了“图”部分的算法及其实现方法。
这让我对数据结构这门课程都有了更深层次的体会。
进行课程设计的确会对本课程的学习有很大的帮助。