动态连接(Dynamic connectivity)的问题
所谓的动态连接问题是指在一组可能相互连接也可能相互没有连接的对象中,判断给定的两个对象是否联通的一类问题。这类问题可以有如下抽象:
- 有一组构成不相交集合的对象
- union: 联通两个对象
- find: 返回两个对象之间是否存在一条联通的通路
在使用union-find处理动态连接的问题时,我们一般将这一组对象抽象为一个数组。
对于这组对象,其中相互连接的一些对象构成的子集称为联通集。
算法目的:能够在如下条件下高效解决动态连接的问题
Union
命令和Find
命令可能交替被调用- 操作的总数
M
可能很大 - 集合中的对象数目
N
可能很大
Quick find
数据结构:
- 输入数组
id[]
的长度为N
。且每一个对象最初的id
都为其本身。 - 当且仅当
p
和q
具有相同的id
时p
和q
才是联通的。 id[]
数组中存储对应对象所属的联通集的root的id。
算法:
Union
:欲将p
和q
相连,相当于合并包含p
的联通集和包含q
的联通集,也就是将所有id
与id[p]
相同的对象的id
改为id[q]
。Find
:检查p
和q
的id
是否相同即可。
示例:
对于下表所示的对象集合,如果我们调用union(1,3)
,则需要将所有id
为2
的对象的id
改为4
。经过这个操作之后,原先的两个联通集[1,2]
与[3,4]
如今成为了一个联通集。
| i | 0 | 1 | 2 | 3 | 4 |
| id[i] | 0 | 2 | 2 | 4 | 4 |
==>
| i | 0 | 1 | 2 | 3 | 4 |
| id[i] | 0 | 4 | 4 | 4 | 4 |
Quick find的Java实现
public class QuickFind {
int[] id;
public QuickFind(int n) {
id