联合在不同情况下查找操作

时间:2017-11-11 14:20:51

标签: c algorithm data-structures union-find

这是来自数据结构书的段落,由 Narasimha Karumanchi(不相交集ADT)

快速查找实施(快速查找)

此方法使用数组,其中数组包含每个元素的集名称。

在此表示中执行并集(a,b)[假设a,在集合i和b在集合j中]我们需要扫描完整数组并将所有i更改为j。这需要O(n)。

我的问题1

如果查找操作需要O(1)那么为什么扫描完整数组并将所有i更改为j,只需要更改其中两个,那么它是如何O(n)

============

(第8.8节)

使用存储每个元素的父元素而不是使用root作为其集合名称的数组,求解union O(n)

我的2.问题

如何解决使用父母的问题? 根和父方法如何为我们提供偏斜树?

1 个答案:

答案 0 :(得分:1)

考虑到2个集合中有8个元素,其中集合标识符为1和2(因此在描述中i = 1且j = 2)。 假设4个元素在集合1中(元素0,1,3,7),4个元素在集合2中(元素2,4,5,6)。

快速查找实现将此数组表示为:

[ 1, 1, 2, 1, 2, 2, 2, 1 ]

如下面的表示(元素1和2都有自循环):

     1           2
   / | \       / | \
  0  3  7     4  5  6

如果执行union(1,2)并且只更新set标识符(让我们假设我们正在更新set 2中的元素以指向set 1),那么你将拥有一个数组,如:

[ 1, 1, 1, 1, 2, 2, 2, 1 ]

如果执行find(2),则得到标识符1,这是正确的。 但是如果执行find(4),你会得到标识符2,这是不正确的,因为元素4现在属于集合1。

所以你必须扫描完整的数组(因此操作有时间复杂度O(n))来更新标识符,以便在联合操作时得到以下数组:

[ 1, 1, 1, 1, 1, 1, 1, 1 ]

以下表示(1表示自循环)

         1
   / / | | \ \ \
  0 2  3 4  5 6  7

我确定你会在本书后面看到,union-find数据结构有更高效的实现,它们基于秩和路径压缩的联合。