并查集(Union-Find)是一种常见的数据结构,它主要用于解决连通性问题,如判断两个节点是否属于同一个子集或者组。并查集有两个主要操作:联合(Union)和查找(Find)。查找操作用于确定某个元素所在的子集,而联合操作则将两个子集合并为一个。
以下是并查集的基本实现(以 Python 为例):
class UnionFind:
def __init__(self, n):
self.parent = list(range(n)) # 初始化时,每个元素的父节点指向自己
def find(self, x):
# 查找过程中进行路径压缩,将查找路径上的每个节点直接连接到根节点
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x])
return self.parent[x]
def union(self, x, y):
# 将两个子集合并为一个,即将一个子集的根节点连接到另一个子集的根节点
root_x = self.find(x)
root_y = self.find(y)
if root_x != root_y:
self.parent[root_x] = root_y # 或者 self.parent[root_y] = root_x,效果相同
# 使用示例
uf = UnionFind(5) # 创建一个包含5个元素的并查集
uf.union(0, 1) # 将元素0和1合并到同一个子集中
uf.union(1, 2) # 将元素1和2合并到同一个子集中,由于1已经和0合并,因此现在0、1、2都在同一个子集中
print(uf.find(0) == uf.find(2)) # 判断元素0和2是否在同一个子集中,输出 True
这个实现中,我们使用了路径压缩技术来优化查找操作的时间复杂度。路径压缩是在查找过程中,将查找路径上的每个节点直接连接到根节点,从而减小树的高度,提高后续查找的效率。这种优化可以将查找操作的时间复杂度降低到接近 O(1)。
并查集常用于解决图的连通性问题,例如判断无向图中的两个节点是否连通。在这种情况下,可以将图中的每个节点看作并查集中的一个元素,然后通过遍历图的边来合并相应的节点子集。最后,通过查找操作来判断两个节点是否属于同一个子集,即是否连通。