Kruskal 与堆或排序算法

Kruskal with Heap or Sort Algorithm

我正在尝试尽可能高效地实施 Kruskal。

为了运行效率,使用堆或排序算法对边缘进行排序有区别吗?

还有哪些其他技术可以使 Kruskal 算法更有效地工作?

这取决于您要解决的确切问题。如果您正在实施通用解决方案,只需选择 'fastest' 排序算法。我怀疑那是堆排序。我会使用 Java 默认使用的任何算法作为排序算法(如果您正在排序对象,可能是 timsort)。此外,在某些情况下,排序可以比 O(ElogE) 更快地完成。假设你的边只能有一个小区间内的整数权重,那么也许你可以选择与计数排序非常相似的东西。因此,如果您属于其中一种情况,那么堆可能远不是一个好的选择。 此外,我看不出有任何理由有人会单独在 Kruskal 算法的上下文中使用堆。

要回答您的第二个问题(但您可能已经知道这一点),使用 Disjoint-set data structure 可以很好地加快集合上的操作。它具有各种优点:易于实现、良好的渐近行为和低常数。

编辑

我重新考虑了 heap/heapsort 选项,主要是因为我的 post 上的评论。如果只排序直到树完成,使用堆可能确实会带来巨大的优势。 180度开启我的观点。这就是原因。

考虑 Erdős–Rényi model。现在,这是一个非常简单的模型,其中从 n 个顶点(即没有边)上的空图 G 开始,然后将每个可能的边以 p 的概率添加到 G,独立于任何其他边缘。这不完全是 Kruskal 算法在组成树时所做的,但它类似于 'pretty well' 如果 G 具有二次数的边(根据顶点数),则边分布不是 'biased' 并且权重分配不是 'biased'。

有趣的部分来了。在 Erdős–Rényi 模型下,当 p 大约为 ln(n)/n 时(即 'roughly' 说,在向图中添加 O(nln(n)) 条边之后,图变得连通。结果在一段时间内众所周知(检查here)。

尽管 Kruskal 算法的设置再次不同,如果 G 的边数是二次方(就顶点数而言),则边分布不是 'biased' 并且权重分配不是 'biased',一棵树在 O(nln(n)) 边内可达是合理的。如果这确实是真的,那么使用堆并且只排序直到树完成比在开始组合树之前使用比较排序方法对整组边进行排序要好。

所以使用堆可能也会带来运行时速度的提升,而且可能相当可观。