data-structures - 如何在 UnionFind 数据结构中正确实现加权联合和路径压缩
问题描述
我正在尝试在 C 中实现 Union-Find/Disjoint-Set 数据结构,在 Find 中使用加权联合和路径压缩。与非加权联合相比,我对如何实施加权联合以降低时间复杂度有一些疑问。
我已经在网上找到了几个解决这个问题的方法,并实现了我自己的。在每个解决方案中,每个单独树的根(代表一个集合)始终保存树的节点数。当联合属于不同集合的两个随机对象的集合时,首先找到根(这里使用路径压缩),然后我们比较这些根的大小。最大树的根被设置为最小树的根的父节点。
然而,在我的理解中,我们试图通过加权联合来实现的是降低生成树的高度(这也是我们试图通过路径压缩来实现的)。因此,应该连接到另一棵树的不是节点数最少的树,而是高度最低的树。这将高度保持在最低限度。
它是否正确?考虑到实现的其余部分,检查高度和大小是否等效(我们总是从多个单个(一个节点)集开始)?
假设需要检查的是高度,那么在不使用路径压缩的情况下跟踪树的高度是相当简单的。然而,当使用路径压缩时,我还没有找到一种方法来跟踪树的高度(至少在不遍历整个树的情况下不会,这会增加“查找”算法的时间复杂度。
这是我发现并使用我在 C++ 中描述的(与我编码的非常相似)的实现示例: https ://github.com/kartikkukreja/blog-codes/blob/master/src/Union%20Find %20(不相交%20Set)%20Data%20Structure.cpp
解决方案
看起来你自己已经想通了。
Union-by-height 是制作最短树的明显方法,但是当您使用路径压缩时很难跟踪高度......
因此,通常使用按等级联合。如果我们不进行任何路径压缩,集合的“等级”就是它的高度,所以当您使用路径压缩的等级联合时,就像从高度联合开始,然后应用路径压缩为优化,确保路径压缩不会改变合并的工作方式。
然而,很多人(包括我自己)使用 union-by-size,因为大小通常很有用,并且可以证明 union-by-size 产生与 union-by-rank 相同的最坏情况复杂性。同样在这种情况下,路径压缩不会影响合并,因为它不会改变任何根的大小。
推荐阅读
- bash - 如何使用 slurm 使用 worker/master 概念在不同节点上运行不同的独立并行作业?
- mysql - 在 Windows 上安装 MySql 8.0 和 Visual C++ Redistributable 疑难解答
- arrays - UserForm 变量范围:将二维数组值从 userform2 传输到 userform1
- arrays - 创建 Swift 数组的最快方法
具有固定计数 - vue.js - 如何将此 src 绑定到 vue js 中的 iFrame?
- excel - VBA代码在引用从B列到D列的一系列单元格时创建文件夹和子文件夹?
- python - 使用从 URL / Postcode 到 NUTS1 映射的文本文件创建 SQLite 数据库
- angular - 子目录上的 Laravel
- r - 如何让这个标签指向最左边的栏?
- java - YAMLBeans - a 的预期数据
但找到的字段:标量