Union-Find(Disjoint Set Union)追踪将元素划分为互不相交的集合,并支持两个接近 O(1) 的操作:find(x 在哪个集合中?)和 union(合并两个集合)。它在连通性查询中表现出色。
基本思想
每个集合是一棵以代表性根节点为首的树。通过路径压缩和按秩/大小合并,操作以接近常数的摊销时间运行(逆阿克曼函数,α(n))。
class UnionFind:
def __init__(self, n):
self.parent = list(range(n))
self.rank = [0] * n
def find(self, x):
while self.parent[x] != x:
self.parent[x] = self.parent[self.parent[x]] # compress
x = self.parent[x]
return x
def union(self, a, b):
ra, rb = self.find(a), self.find(b)
if ra == rb:
return False # already connected
if self.rank[ra] < self.rank[rb]:
ra, rb = rb, ra
self.parent[rb] = ra # attach smaller under larger
if self.rank[ra] == self.rank[rb]:
self.rank[ra] += 1
return True
没有路径压缩和按秩合并,树会退化为 O(n) 的链。它不支持集合的高效分割。
并查集以几乎零成本回答