一些应用涉及将n个不同的元素分成一组不相交的集合。这些应用经常需要进行两种特别的操作:寻找包含给定元素的唯一集合和合并两个集合。用并查集即可实现。
一个不相交集合数据结构维护了一个不相交动态集的集合S={S1,S2,... ,Sk}。我们用一个代表来标识每个集合,它是这个集合的某个成员。
我们希望支持以下三种操作:
MAKE-SET(x):建立一个新的集合,它的唯一成员(因而为代表)是x。因为各个集合是不相交的,故x不会出现在别的集合中。
UNION(x,y):将包含x和y的两个动态集合(表示为Sx和Sy)合并成一个新的集合,即这两个集合的并集。同时还要消除Sx和Sy。
FIND-SET(x):返回一个指针,这个指针指向包含x的(唯一)集合的代表。
应用:确定无向图的连通分量。
CONNECTED-COMPONENTS(G)
for each vextex v∈G.V
MAKE-SET(v)
for each edge(u,v)∈G.E
if FIND-SET(u)≠FIND-SET(v)
UNION(u,v)
SAME-COMPONENT(u,v)
if FIND-SET(u)≠FIND-SET(v)
return TRUE
else return FALSE
不相交集合的链表表示(略)
不相交集合森林
在森林中,每棵有根树代表一个集合,树中的每个结点包含一个成员,每个成员仅仅指向它的父结点。每棵树的根包含集合的代表,并且是其自己的父结点。
MAKE-SET操作简单地创建一颗只有一个结点的数,FIND-SET操作通过沿着指向父结点的指针找到树的根。这一通向根结点的简单路径上所访问的结点构成了查找路径(find path)。UNION操作得到一棵树的根指向另外一棵树的根。
伪代码如下(其中FIND-SET带有路径压缩):
MAKE-SET(x)
x.p=x
x.rank=0
UNION(x,y)
LINK(FIND-SET(x),FIND-SET(y))
LINK(x,y)
if x.rank>y.rank
y.p=x
else x.p=y
if x.rank==y.rank
y.rank=y.rank+1
FIND-SET(x)
if x≠x.p
x.p=FIND-SET(x.p)
return x.p