博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
最小生成树---Kruskal/Prime算法
阅读量:4561 次
发布时间:2019-06-08

本文共 2945 字,大约阅读时间需要 9 分钟。

1.Kruskal算法

      图的存贮采用边集数组或邻接矩阵,权值相等的边在数组中排列次序可任意,边较多的不很实用,浪费时间,适合稀疏图。

     方法:将图中边按其权值由小到大的次序顺序选取,若选边后不形成回路,则保留作为一条边,若形成回路则除去.依次选够(n-1)条边,即得最小生成树.(n为顶点数)。

    Kruskal算法在图G=(V,E)上的运行时间取决于分离集合这一数据结构如何实现。采用在分离集合中描述的按行结合和通路压缩的启发式方法来实现分离集合森林的结构,这是从渐近意义上说,目前最快实现法。初始化占用时间O(V),对边排序需时间为O(E㏒E);对分离集的森林要进行O(E)次操作,共需时间为O(Ef(E,V)),其中f函数为Ackerman函数的反函数。因f(E,V)=O(㏒E),所以KruskaI全部运行时间为O(EE)

          

1 /*********************Kruskal算法********************/ 2 void Init_Kruskal_MST(void) 3 { 4     count=0; //边计数 5     sum_mst=0;  //权值和 6     memset(MST,0,sizeof(MST));  7     qsort(ESA,e,sizeof(ESA[0]),myComp);  //按权值快速排序 8 }                                        //注意调用方法 9 10 void Kruskal_MST(void)11 {12     int cn=0;13     int u,v;14     15     while(count < n-1)  //边数判断16     {17         u=ESA[cn].from;18         v=ESA[cn].to;19 //        cn++;20 21         if(Find(u) != Find(v))22         {23             MST[count].from=vertex[u];24             MST[count].to=vertex[v];25             count++;26             sum_mst+=ESA[cn].wg;27             Union(u,v);28         }29         cn++;  //注意位置30     }31 }

2.Prime算法

        方法:从指定顶点开始将它加入集合中,然后将集合内的顶点与集合外的顶点所构成的所有边中选取权值最小的一条边作为生成树的边,并将集合外的那个顶点加入到集合中,表示该顶点已连通.如此下去直到全部顶点都加入到集合中,即得最小生成树.

  ①    置顶点集合V和边集E,它们的初始状态为空集。

  ②    任意选取一个顶点A加入V中。 

  ③    复以下过程直到V中已经包含原图的所有节点: 

    1、选一条权值最小的边(u,v),并使其满足u,v两节点只有一个在点集V中。

    2、将两个节点中不在V的那个点加入集合V中,并将边(u,v)加入边集E中。

   ④    所得的子图G’=(V,E)即为所求的最小生成树。

     任意时刻的中间结果都是一棵树,每次花费最小的代价,用一条边把不在树中的结点加进来。按结点来贪,因此适用于稠密图的处理. 关键:找出当前最优得一条边,穷举每一条不在集合E中的边,找出符合条件且最优的边。邻接矩阵:O(v2) 。

1 void Init_Prime_MST(void) 2 { 3     flag=0; 4     sum_mst=0; 5     count=0; 6     for(int i=0;i
n;i++) 7 { 8 vis[i]=0; 9 min_wg[i]=MG->edge[START][i]; //记录以i为终点的最小权值10 min_from[i]=START; //记录最小权值边的起点11 }12 count=1; //默认第一个节点[编号0]已选【可以更改】13 vis[START]=1;14 min_from[START]=START;15 }16 17 void Prime_MST(void)18 {19 int min,to_index; //权值中间量,对应的到达顶点索引index20 21 while(count < MG->n)22 {23 min=INF;24 to_index=-1;25 for(int i=0;i
n;i++)26 if(!vis[i] && (min_wg[i] < min))27 {28 min=min_wg[i];29 to_index=i;30 }31 32 if(to_index != -1) //找到终点33 {34 vis[to_index]=1;35 sum_mst+=min;36 MST[count-1].from=MG->vertex[min_from[to_index]];37 MST[count-1].to=MG->vertex[to_index];38 count++;39 40 if(count == MG->n)41 flag=1;42 }43 else44 break;45 46 for(int j=0;j
n;j++) //更新dist,使不在生成树上的点到生成树上的点的距离最小,直到所有的点都在生成树上。47 if(!vis[j] && (min_wg[j] > MG->edge[to_index][j]))48 {49 min_wg[j]=MG->edge[to_index][j]; /* 更新权值信息 */50 min_from[j]=to_index; /* 更新最小权值边的起点 */51 }52 }53 }

转载于:https://www.cnblogs.com/wjcx-sqh/p/5929921.html

你可能感兴趣的文章
React Children
查看>>
大数据等最核心的关键技术:32个算法
查看>>
Maven多模块项目搭建
查看>>
redis列表list
查看>>
雷林鹏分享: C# 简介
查看>>
ORA-12505: TNS: 监听程序当前无法识别连接描述符中所给出的SID等错误解决方法
查看>>
实用类-<Math类常用>
查看>>
构建之法阅读笔记之四
查看>>
10.15习题2
查看>>
Windows Server 2008 R2 备份与恢复详细实例
查看>>
Ubuntu上kubeadm安装Kubernetes集群
查看>>
关于java学习中的一些易错点(基础篇)
查看>>
MFC的多国语言界面的实现
查看>>
四则运算个人项目 最终版
查看>>
java线程系列---java5中的线程池
查看>>
SQL表连接
查看>>
新秀系列C/C++经典问题(四)
查看>>
memset函数具体说明
查看>>
经常使用的android弹出对话框
查看>>
确保新站自身站点设计的合理性的六大注意点
查看>>