并查集(Union Find)

定义

并查集(Union Find)是二叉树结构的衍生,用于高效解决无向图的连通性问题。它可以在 O(1) 时间内完成合并、查询和统计操作,且只需一个数组实现,无需构建完整的图结构(邻接表/邻接矩阵)。

核心操作(API)

class UF {
    // 初始化并查集,包含 n 个节点,时间复杂度 O(n)
    public UF(int n);

    // 连接节点 p 和节点 q,时间复杂度 O(1)
    public void union(int p, int q);

    // 查询节点 p 和节点 q 是否连通,时间复杂度 O(1)
    public boolean connected(int p, int q);

    // 查询当前的连通分量数量,时间复杂度 O(1)
    public int count();
}

动态连通性问题

并查集解决的核心问题:

  1. 连接操作:将图中的两个节点连通
  2. 连通查询:判断两个节点是否连通(考虑传递性)
  3. 统计连通分量:查询当前图中共有多少个连通分量

连通关系的性质

  1. 自反性:节点 p 和 p 自身是连通的
  2. 对称性:如果节点 p 和 q 连通,那么 q 和 p 也连通
  3. 传递性:如果 p 和 q 连通,q 和 r 连通,那么 p 和 r 也连通

传递性是连通关系的核心特性,使得不能简单地通过邻接表判断连通性,必须使用并查集或图遍历算法。

为什么需要并查集

传统方法使用 DFS/BFS 遍历判断连通性:

  • connected 方法:需要 O(V+E) 时间进行图遍历
  • count 方法:需要 O(V+E) 时间遍历整幅图统计连通分量

并查集的优势:

  • 所有操作均为 O(1) 时间复杂度
  • 不需要构建图结构,只需一个 parent 数组
  • 适合处理动态连通性问题(边逐步增加的情况)

应用场景

  • 判断无向图的连通性
  • Kruskal 最小生成树算法中的环检测
  • 动态连通性问题(如编译器判断同一内存对象的不同引用)
  • 社交网络中的朋友圈计算
  • 森林中多棵树的根节点管理(如 N 叉树森林)

相关概念

  • :并查集常用于图算法
  • 最小生成树算法:Kruskal 算法使用并查集检测环
  • 无向图:并查集专用于无向图连通性问题
  • 连通分量:并查集维护的核心指标
  • 多叉树:并查集本质是多叉树森林
  • DFS:传统连通性判断方法,时间复杂度更高
  • BFS:传统连通性判断方法,时间复杂度更高

Interactive Graph