不相交集合数据结构

概述

不相交集合数据结构(Disjoint-Set / Union-Find / 并查集)维护一组不相交动态集合 的划分,支持高效的合并(UNION)和查询(FIND-SET)操作。它是处理等价关系连通分量问题的核心数据结构。

定义

不相交集合数据结构

维护一个元素集合 的一个划分(partition),即一组两两不相交的子集 ,满足:

  • 对所有

每个子集 称为一个集合(set),每个集合有一个代表(representative)来标识该集合。

三个核心操作

操作语法功能
MAKE-SETMAKE-SET(x)创建一个仅含元素 的新单元素集合
UNIONUNION(x, y)将包含 的集合与包含 的集合合并
FIND-SETFIND-SET(x)返回包含 的集合的代表元素

操作的不变式

  • FIND-SET(x) = FIND-SET(y) 当且仅当 属于同一个集合
  • MAKE-SET(x) 之后, 单独构成一个集合,FIND-SET(x) = x

典型应用

  1. 连通分量维护:在无向图中,动态添加边时维护连通分量
  2. 等价关系维护:判断两个元素是否属于同一等价类
  3. 最小生成树(Kruskal 算法):判断加入边是否会形成环
  4. 迷宫生成:随机化 Prim/Kruskal 迷宫生成算法

发明历史

  • 1973:Hopcroft & Ullman 提出按秩合并,达到
  • 1975:Tarjan 提出路径压缩,与按秩合并结合达到
  • 1989:Fredman & Saks 证明 的下界,确认 是最优的

四种实现的复杂度对比

实现方式MAKE-SETFIND-SETUNION 次操作总复杂度
链表(无优化)
链表 + 加权合并启发式*
森林 + 按秩合并*
森林 + 按秩合并 + 路径压缩

*UNION 通过两次 FIND-SET + 一次 LINK 实现,均摊意义下的代价。

关键观察

最优实现(森林 + 按秩合并 + 路径压缩)的每次操作均摊代价为 ,其中 反阿克曼函数。由于 对所有实际可能的 成立,因此在实践中可以视为

第21章:最小生成树

Kruskal算法是并查集最经典的应用场景。算法将图的边按权排序后逐条处理:对每条边 (u,v),使用 FIND-SET(u) ≠ FIND-SET(v) 判断 u 和 v 是否已在同一连通分量中。若不在同一分量,则 UNION(u,v) 合并两个分量并将边加入MST。使用按秩合并+路径压缩的并查集,Kruskal总时间 O(E α(V)),其中 α 是反阿克曼函数。

参见