183 algorithm graph-theory minimum-spanning-tree prims-algorithm kruskals-algorithm
我想知道什么时候应该使用Prim的算法,什么时候Kruskal才能找到最小的生成树?它们都具有简单的逻辑,同样最坏的情况,唯一的区别是实现可能涉及一些不同的数据结构.那么决定因素是什么?
Tod*_*lin 192
当您有一个包含大量边的图时,请使用Prim的算法.
对于具有V顶点E边的图,Kruskal的算法在O(E log V)时间内运行,而Prim的算法可以在O(E + V log V)的摊销时间内运行,如果使用斐波那契堆.
当你有一个比顶点更多的边缘的真密图时,Prim的算法明显更快.Kruskal在典型情况下(稀疏图)表现更好,因为它使用更简单的数据结构.
Sni*_*las 97
我在网上发现了一个非常好的线程,以一种非常简单的方式解释了它的不同之处:http://www.thestudentroom.co.uk/showthread.php?t = 232168.
Kruskal的算法将通过添加下一个最便宜的边缘从最便宜的边缘增长解决方案,前提是它不会创建一个循环.
Prim的算法将通过添加下一个最便宜的顶点来增加随机顶点的解决方案,该顶点当前不在解决方案中但通过最便宜的边缘连接到顶点.
附件是关于该主题的有趣表格.

如果你以最佳形式同时实现Kruskal和Prim:分别使用union find和finbonacci堆,那么你会注意到与Prim相比,Kruskal如何易于实现.
使用斐波纳契堆的Prim更难,主要是因为您必须维护一个记账表来记录图节点和堆节点之间的双向链接.使用Union Find,相反,结构简单,甚至可以直接生产mst,几乎不需要额外费用.
mal*_*ouk 28
我知道你没有要求这个,但如果你有更多的处理单元,你应该总是考虑Borůvka的算法,因为它可能很容易并行化 - 因此它比Kruskal和Jarník-Prim算法具有性能优势.
小智 16
Kruskal时间复杂度最差的情况是O(E log E),这是因为我们需要对边缘进行排序. 最坏情况下的Prim时间复杂度是具有优先级队列的O(E log V)或者甚至更好,具有Fibonacci Heap的O(E + V log V).当图形稀疏时,我们应该使用Kruskal,当边缘已经排序或者我们可以在线性时间内对它们进行排序时,可以使用边缘的小数量,例如E = O(V).当图形密集时,我们应该使用Prim,即边数很高,如E = O(V²).
Kruskal算法的一个重要应用是单链路聚类.
考虑n个顶点,你有一个完整的图.要获得那些n个点的ak簇.运行Kruskal的算法在有序边集的第一个n-(k-1)边上.你得到图的k-簇最大间距.