导读:本期聚焦于小伙伴创作的《如何用C++实现带路径压缩的并查集算法优化连通性快速判定逻辑》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何用C++实现带路径压缩的并查集算法优化连通性快速判定逻辑》有用,将其分享出去将是对创作者最好的鼓励。

并查集是一种用于管理不相交集合的数据结构,核心功能包括查询两个元素是否属于同一集合、合并两个集合,在图连通性判定、社交网络关系分析、最小生成树构建等场景中有广泛应用。基础的并查集实现查找根节点时可能产生较长的链结构,导致时间复杂度偏高,而路径压缩优化可以在查找过程中将节点的父节点直接指向根节点,大幅缩短后续查找的路径长度。

如何用C++实现带路径压缩的并查集算法优化连通性快速判定逻辑

并查集核心原理

并查集通常用数组来存储每个元素的父节点,初始时每个元素的父节点指向自身,代表每个元素都是独立的集合。两个核心操作分别是find查找根节点和union合并集合:

  • find(x):查找元素x所在集合的根节点,路径压缩优化就在这个操作中实现
  • union(x, y):将元素x和元素y所在的集合合并,通常将其中一个集合的根节点指向另一个集合的根节点

带路径压缩的C++实现源码

以下是完整的优化版并查集实现,包含初始化、查找、合并和连通性判定四个核心方法:

#include <iostream>
#include <vector>
using namespace std;

class UnionFind {
private:
    vector<int> parent;  // 存储每个元素的父节点
    vector<int> rank;    // 存储每个集合的秩,用于优化合并逻辑,避免树过高
    int count;           // 当前独立集合的数量

public:
    // 初始化并查集,n为元素总数
    UnionFind(int n) {
        count = n;
        parent.resize(n);
        rank.resize(n, 0);
        // 初始时每个元素的父节点指向自身
        for (int i = 0; i < n; i++) {
            parent[i] = i;
        }
    }

    // 带路径压缩的查找操作,返回元素x的根节点
    int find(int x) {
        // 如果当前节点的父节点不是自身,递归查找父节点的根节点,并将当前节点的父节点直接指向根节点
        if (parent[x] != x) {
            parent[x] = find(parent[x]);
        }
        return parent[x];
    }

    // 合并元素x和元素y所在的集合
    void unite(int x, int y) {
        int rootX = find(x);
        int rootY = find(y);
        // 如果根节点相同,说明已经属于同一集合,不需要合并
        if (rootX == rootY) {
            return;
        }
        // 按秩合并,将秩较小的树合并到秩较大的树上,避免树的高度过高
        if (rank[rootX] < rank[rootY]) {
            parent[rootX] = rootY;
        } else if (rank[rootX] > rank[rootY]) {
            parent[rootY] = rootX;
        } else {
            // 秩相等时,任意合并,合并后目标树的秩加1
            parent[rootY] = rootX;
            rank[rootX]++;
        }
        // 合并后独立集合数量减1
        count--;
    }

    // 判断元素x和元素y是否属于同一集合
    bool isConnected(int x, int y) {
        return find(x) == find(y);
    }

    // 返回当前独立集合的数量
    int getCount() {
        return count;
    }
};

// 测试示例
int main() {
    // 初始化5个元素的并查集
    UnionFind uf(5);
    // 合并0和1
    uf.unite(0, 1);
    // 合并1和2
    uf.unite(1, 2);
    // 判定0和2是否连通
    cout << "0和2是否连通: " << (uf.isConnected(0, 2) ? "是" : "否") << endl;
    // 判定0和3是否连通
    cout << "0和3是否连通: " << (uf.isConnected(0, 3) ? "是" : "否") << endl;
    // 合并3和4
    uf.unite(3, 4);
    cout << "当前独立集合数量: " << uf.getCount() << endl;
    return 0;
}

算法复杂度分析

未优化的并查集find操作最坏时间复杂度为O(n),而加入路径压缩和按秩合并优化后,findunion操作的平均时间复杂度接近O(1),严格来说是阿克曼函数的反函数级别,在实际应用中可以认为是常数时间,非常适合处理大规模数据的连通性判定场景。

实际应用场景

该优化版并查集可以应用在多个实际开发场景中:

  • 图论中的连通分量统计,比如判断一个无向图有多少个连通子图
  • 最小生成树算法中的边筛选,比如Kruskal算法中判断加入边是否会形成环
  • 社交网络中判断两个用户是否存在间接好友关系
  • 动态连通性问题,比如网络连接中判断两个节点是否可达

C++并查集路径压缩连通性判定union_find修改时间:2026-07-06 20:33:23

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。