在算法和数据结构的世界中,不相交集合(Disjoint Set)是一种非常实用且高效的数据结构,常用于处理动态连通性问题。它也被称为并查集(Union-Find)。本教程将带你从零开始,用 Java 语言实现一个完整的不相交集合,并解释其核心思想与优化技巧。无论你是编程小白还是有一定基础的开发者,都能轻松掌握!
不相交集合是一种用于管理一组元素的集合,这些集合之间互不相交(即没有公共元素)。它支持两种基本操作:
不相交集合广泛应用于以下场景:
我们首先用数组来实现一个简单的不相交集合。每个元素的父节点存储在数组中,初始时每个元素都是自己的父节点。
public class DisjointSet { private int[] parent; // 构造函数:初始化 n 个元素 public DisjointSet(int n) { parent = new int[n]; for (int i = 0; i < n; i++) { parent[i] = i; // 每个元素初始时是自己的根 } } // 查找 x 所在集合的根 public int find(int x) { if (parent[x] != x) { return find(parent[x]); } return x; } // 合并 x 和 y 所在的集合 public void union(int x, int y) { int rootX = find(x); int rootY = find(y); if (rootX != rootY) { parent[rootX] = rootY; } }} 上面的基础版本在最坏情况下效率较低。我们可以使用两种经典优化技术:
下面是优化后的完整 Java 实现:
public class OptimizedDisjointSet { private int[] parent; private int[] rank; // 用于记录树的高度(秩) public OptimizedDisjointSet(int n) { parent = new int[n]; rank = new int[n]; for (int i = 0; i < n; i++) { parent[i] = i; rank[i] = 0; } } // 带路径压缩的 find public int find(int x) { if (parent[x] != x) { parent[x] = find(parent[x]); // 路径压缩 } return parent[x]; } // 带按秩合并的 union public void union(int x, int y) { int rootX = find(x); int rootY = find(y); if (rootX != rootY) { if (rank[rootX] < rank[rootY]) { parent[rootX] = rootY; } else if (rank[rootX] > rank[rootY]) { parent[rootY] = rootX; } else { parent[rootY] = rootX; rank[rootX]++; } } }} 下面是一个简单的使用示例,演示如何判断两个节点是否连通:
public class Main { public static void main(String[] args) { OptimizedDisjointSet ds = new OptimizedDisjointSet(5); ds.union(0, 1); ds.union(2, 3); ds.union(1, 2); // 检查 0 和 3 是否连通 if (ds.find(0) == ds.find(3)) { System.out.println("0 和 3 在同一个集合中"); } else { System.out.println("0 和 3 不在同一个集合中"); } }} 通过本教程,你已经掌握了 Java不相交集合 的基本原理和实现方法。结合 路径压缩 与 按秩合并,并查集的操作接近常数时间复杂度(阿克曼函数的反函数),效率极高。
无论是准备面试、刷 LeetCode,还是开发实际项目,Union-Find数据结构 都是你工具箱中不可或缺的利器。快动手试试吧!
关键词回顾:Java不相交集合、并查集教程、Union-Find数据结构、Java实现并查集
本文由主机测评网于2025-12-13发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025127009.html