请提供一个简单而简单的方法来分析union-find算法的时间复杂度。在这两个案例中 1.标准方法 2.加权联合启发式方法
我知道在标准版本中它的时间复杂度是: O(n ^ 2) 在加权联合启发式方法的情况下,它是: O(m + n logn)
但我没有得到,它是怎么来的。 假设:考虑有n个elemetns和Linked list数据结构,每个节点指向列表的头部,m = make set operations。
答案 0 :(得分:0)
首先是一些定义: m 是生成集操作的数量。 n 是联合/查找操作的总和。
标准版
假设join(a,b)
使b
成为a
的根。
如果调用序列为 0.5n ,则调用joint(1,2)
,joint(2,3)
,joint(3,4)
,您可以创建一个 0.5n的链 buttom中具有1
的节点。然后find(1)
将花费 0.5n 时间,因此调用 0.5n 次并且您的运行时将 0.25n ^ 2 = O(n ^ 2 )
由于我们必须执行 m makeset
操作,我们最终会得到O(m + n ^ 2)。
<强>加权联盟强>
我假设权重是集合的大小(而不是排名)。
对于给定的集合,让 h 为表示它的树的高度, w 的大小。 find
在该集合中最多需要 h 时间。通过归纳,我们可以证明 h <= log(w)。
对于 w = 1 且 h = 0 的单个节点,该公式很容易保留。
现在考虑两个树 a 和 b 之间的连接,其中 a 成为新的根。假设 h&lt; = log(w)适用于 a 和 b ,我们将显示它也适用于联合。我们知道 wa&gt; = wb =&gt; wab = wa + wb&gt; = 2wb 。如果 a 严格高于 b ,我们有 hab = ha&lt; = log(wa)&lt; = log(wab)。否则(当 hb&gt; = ha 时)我们有 hab = 1 + hb&lt; = 1 + log(wb)= log(2wb)&lt; = log(wab)
这证明 h&lt; = log(w)成立。在较少的数学术语中,我们已经证明任何集合的高度小于其大小的对数,因此查找最多需要 O(log(k))时间,其中k是大小的集。
让 j 成为联合操作的数量。每个union
触及2个元素,因此任何集合的最大大小都以 2j 为界。
union和finds的运行时因此是 O(j + k log(2j))= O(n + n log(2n))= O(n log(n))。我们必须再做 m makeset
s,所以我们得到 O(m + n log(n))