这是来自数据结构书的段落,由 Narasimha Karumanchi(不相交集ADT)
此方法使用数组,其中数组包含每个元素的集名称。
在此表示中执行并集(a,b)[假设a,在集合i和b在集合j中]我们需要扫描完整数组并将所有i更改为j。这需要O(n)。
如果查找操作需要O(1)那么为什么扫描完整数组并将所有i更改为j,只需要更改其中两个,那么它是如何O(n)
============
如何解决使用父母的问题? 根和父方法如何为我们提供偏斜树?
答案 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数据结构有更高效的实现,它们基于秩和路径压缩的联合。