并查集
概念
并查集(
D
i
s
j
o
i
n
t
s
e
t
或
U
n
i
o
n
−
f
i
n
d
s
e
t
Disjoint set 或 Union-find set
Disjointset或Union−findset)是一种树形的数据结构,常用于处理一些不相交集合的合并及查询问题。主要包含以下两种操作:
查询(
F
i
n
d
Find
Find):查询某个元素在哪个集合里
合并(
U
n
i
o
n
Union
Union):合并两个元素所在的不同的集合
集合的表示:每个集合选定一个固定的元素作为该集合的代表,即代表元素,用该代表元素来标识这个集合
集合的存储:每一个集合用树表示,树中的每一个节点保存着到其父节点的引用,则每个集合的代表元素便是集合的根节点
双亲表示法:用数组
f
a
t
h
e
r
[
]
father[ ]
father[]存储和描述并查集
在这个树中我们可以表示为
f
a
t
e
h
r
[
2
]
=
1
,
f
a
t
h
e
r
[
3
]
=
1
,
f
a
t
h
e
r
[
4
]
=
3
fatehr[2]=1, father[3]=1, father[4]=3
fatehr[2]=1,father[3]=1,father[4]=3 ,注意根节点由于不存在父节点,所以使用一个特殊元素来标识
f
a
t
h
e
r
[
1
]
=
−
1
father[1]=-1
father[1]=−1
基本实现
查询(Find)
给定任意元素,返回他所在集合的标号
基本方法:根据其父节点的引用向根节点进行遍历,到达树根并返回代表元素
Python实现:
def Find(x):
p = x
while father[p] > 0:
p = father[p]
return p
时间复杂度:O(n) 线性扫描,n相当于节点的个数
合并(Union)
给定两个集合的元素x和y,把这两个集合进行合并
基本方法:找到x和y所在集合的根节点,将一颗树的根连接到另一个树的根
Python实现:
def Union(x, y):
xRoot = Find(x)
yRoot = Find(y)
father[yRoot] = xRoot
return xRoot
并查集的实现
class UnionFind(object):
def __init__(self, n):
self.father = [-1] * n
def Find(self, x):
p = x
while self.father[p] != -1:
p = self.father[p]
return p
def Union(self, x, y):
xRoot = self.Find(x)
yRoot = self.Find(y)
self.father[yRoot] = xRoot
return xRoot
# 测试一下。。。
a = UnionFind(5)
# print(a.father)
a.Union(1, 2)
a.Union(4, 3)
a.Union(1, 4)
a.Union(0, 1)
print(a.father)
print(a.Find(3))
执行之后得到的树就应该是这样的
以上就是并查集的基本实现。