Java并查集实现:原理、代码与连通块应用

凌晨两点半
凌晨两点半
发布时间:2026-10-16 | 5人浏览过
原创

本文详细介绍并查集(Disjoint Set Union)在Java中的实现。通过路径压缩优化查询效率,讲解核心函数的逻辑,并结合网络拓扑等实际场景,演示如何利用该结构快速统计连通区域个数。

第1步:理解并查集核心逻辑

并查集是一种树型数据结构,用于处理不相交集合的合并及查询问题。其核心操作包含两个部分:

  • 查询(Find/GetFather):确定元素属于哪个集合,即找到元素所在树的根节点。
  • 合并(Union/Join):将两个不同的集合合并为一个集合。

在实际应用中,如果涉及多次跨集合查询,使用并查集可以显著降低时间复杂度,避免重复遍历。

获取根节点与路径压缩

为了优化查询速度,通常采用路径压缩策略。在寻找根节点的过程中,直接将沿途经过的节点的父指针指向根节点,从而扁平化树结构。


public static Integer getFather(int[] father, int u) {
    if (father[u] != u) {
        // 递归查找父节点,并将当前节点u直接指向找到的根节点
        father[u] = getFather(father, father[u]);
    }
    return father[u];
}

逻辑说明:若father[u]等于u,说明已到达根节点;否则递归调用并更新路径,确保下次查询时直接从子节点指向根节点,极大提升后续性能。

合并两个集合

合并操作的思路是找出两个元素的根节点,若根节点不同,则将其中一个根节点的父节点指向另一个根节点,从而实现集合合并。


public static void join(int[] father, int x, int y) {
    int fx = getFather(father, x);
    int fy = getFather(father, y);
    if (fx != fy) {
        father[fx] = fy;
    }
}

关键参数:
- father:存储每个节点父节点的数组。
- x, y:需要合并的两个节点索引。
- 完成状态:执行后,x和y所在的集合将共享同一个根节点fy。

第2步:完整代码验证过程

通过初始化独立集合并逐步合并,观察集合关系的变化。以下示例使用10个节点(0-9)演示合并过程。


public static void main(String[] args) {
    int n = 10;
    int[] a = new int[n];
    
    // 1. 初始化:每个元素自成一个集合
    for (int i = 0; i < n; i++) {
        a[i] = i;
    }
    
    // 打印初始状态
    for (int i = 0; i < n; i++) {
        System.out.println(i + " -> 根节点: " + getFather(a, i));
    }
    
    System.out.println("-------------------------");
    
    // 2. 合并 0 和 1
    join(a, 0, 1); 
    printState(a, n);
    
    // 3. 合并 2 和 3
    join(a, 2, 3); 
    printState(a, n);
    
    // 4. 合并 1 和 3(间接合并了0,1,2,3)
    join(a, 1, 3); 
    printState(a, n);
}

// 辅助方法:打印当前所有节点的根节点状态
private static void printState(int[] father, int n) {
    for (int i = 0; i < n; i++) {
        System.out.println(i + " -> 根节点: " + getFather(father, i));
    }
}

第3步:实际应用场景分析

虽然并查集看似简单,但在处理连通性问题时非常高效。

网络拓扑图的连通块统计

假设有一个包含N个网络设备的拓扑图,已知设备间的连接关系。若要计算共有多少个“局部联通网”(连通分量),步骤如下:

  1. 初始化:每个设备视为一个独立的集合,father[i] = i。
  2. 合并:遍历所有连接边,对每条边的两个设备执行join操作。
  3. 统计:遍历所有设备,利用getFather找出所有根节点。去重后的根节点数量即为局部联通网的个数。

社交网络人际圈判定

类似地,在社交软件中判断“有多少个互不通达的好友圈”,本质就是求图论中的连通块个数。并查集能够以接近线性的时间复杂度动态维护这种关系。

以上就是Java并查集实现与应用的详细内容,更多关于Java数据结构算法优化的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表