并查集 (Union-Find) :从基础到优化

news2024/9/25 18:50:23

并查集 (Union-Find)

并查集是一种树形数据结构,主要用于处理不相交集合(Disjoint Set)的合并和查询问题。它特别适用于解决有关连通性的问题,比如在图论中判断两点是否在同一个连通分量中。并查集可以高效地支持以下两种操作:

  1. 查找(Find):确定某个元素属于哪个集合。
  2. 合并(Union):将两个不同的集合合并为一个集合。

属于集合关系

合并

基础数据结构

每个集合最初由一个元素构成,每个元素都是自己集合的代表。可以用一个数组 parent 来保存每个元素的父节点。而合并操作则在不考虑树的深度的情况下直接将一个集合的根节点指向另一个集合的根节点。

初始化

用一个数组 parent 来表示集合,其中 parent[i] 表示节点 i 的父节点。初始化时,每个元素的父节点都是它自己,即每个元素都是自己集合的代表。
初始化

int[] parent = new int[n];
for (int i = 0; i < n; i++) {
    parent[i] = i;  // 每个元素的父节点指向自己
}

查找(Find)

查找操作用于找到元素所在集合的代表节点(根节点)。通过沿着父节点不断往上查找,直到找到一个节点,它的父节点是它自己,也就找到了根节点。

int find(int x) {
    while (parent[x] != x) {
        x = parent[x];  // 沿着父节点向上查找根节点
    }
    return x;
}

合并(Union)

合并操作将两个集合合并。最简单的方法是找到两个集合的根节点,然后将其中一个根节点指向另一个根节点,不考虑树的深度。

void union(int x, int y) {
    int rootX = find(x);
    int rootY = find(y);
    if (rootX != rootY) {
        parent[rootX] = rootY;  // 将一个根节点指向另一个根节点
    }
}

在这个最基础的实现中,合并操作是随意进行的,不考虑树的结构或平衡性。因此,树可能会变得非常深,甚至变成一条链表,这会导致查找操作的效率降低。

算法优化

路径压缩

在查找操作时,通过让节点直接指向根节点,降低树的深度。
路径压缩

int find(int x) {
    if (parent[x] != x) {
        parent[x] = find(parent[x]); // 路径压缩
    }
    return parent[x];
}

按秩合并

可以理解为一个树的深度(高度)。在合并时,可以将秩较小的树合并到秩较大的树上,使树的深度尽量小。因此加入一个 rank 数组记录节点所在树中的高度,用它来控制合并时的平衡性,初始时每个集合的秩都为 1。
按秩合并

控制逻辑如下:

  • 如果 rank[rootX] > rank[rootY],则令 parent[rootY] = rootX
  • 如果 rank[rootX] < rank[rootY],则令 parent[rootX] = rootY
  • 如果 rank[rootX] == rank[rootY],则可任意指定根节点,同时将秩的值加 1。
void union(int x, int y) {
    int rootX = find(x);
    int rootY = find(y);
    if (rootX != rootY) {
        if (rank[rootX] > rank[rootY]) {
            parent[rootY] = rootX;
        } else if (rank[rootX] < rank[rootY]) {
            parent[rootX] = rootY;
        } else {
            parent[rootY] = rootX;
            rank[rootX]++;
        }
    }
}

代码实现

class UnionFind {
    private int[] parent;
    private int[] rank;

    public UnionFind(int n) {
        parent = new int[n];
        rank = new int[n];
        for (int i = 0; i < n; i++) {
            parent[i] = i;
            rank[i] = 1;
        }
    }

    public int find(int x) {
        if (parent[x] != x) {
            parent[x] = find(parent[x]);
        }
        return parent[x];
    }

    public void union(int x, int y) {
        int rootX = find(x);
        int rootY = find(y);
        if (rootX != rootY) {
            if (rank[rootX] > rank[rootY]) {
                parent[rootY] = rootX;
            } else if (rank[rootX] < rank[rootY]) {
                parent[rootX] = rootY;
            } else {
                parent[rootY] = rootX;
                rank[rootX]++;
            }
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2164487.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

个人博客系统测试(selenium)

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;Yan. yan.                        …

OceanBase 3.X 高可用 (一)

OceanBase 3.X 高可用&#xff08;一&#xff09; 一、分布式核心 OceanBase 3.x 采用的是paxos 协议&#xff0c;与raft协议相比。其复杂程度高&#xff0c;实现技术难度大。 Paxos 协议允许事务日志乱序发送&#xff0c;顺序提交。raft允许事务顺序发送&#xff0c;顺序提…

深度学习:常见损失函数简介--名称、作用和用法

目录 1. L1 Loss 2. NLL Loss (Negative Log Likelihood Loss) 3. NLLLoss2d 4. Gaussian NLL Loss 5. MSE Loss (Mean Squared Error Loss) 6. BCE Loss (Binary Cross-Entropy Loss) 7. Smooth L1 Loss 8. Cross Entropy Loss 1. L1 Loss 作用&#xff1a;计算预测值…

了解通用 SQL 语法

上世纪 90 年代中期&#xff0c;Sun Microsystems 公司推出了一种“一次编写&#xff0c;[随处]运行”的编程语言。这种语言就是 Java。尽管时至今日它仍然是最受欢迎的编程语言之一&#xff0c;但其口号却显得有些过于乐观。Java 语言的发展历程与 SQL 有着诸多相似之处。Java…

C语言常见字符串函数模拟实现一:(strlen,strcpy,strcat,strcmp,strstr )

strlen模拟实现 重点&#xff1a;1.字符串已经\0作为结束标志&#xff0c;strlen返回的是字符串\0前面出现的字符个数&#xff08;不包含\0&#xff09; 2.参数指向的字符串必须要以\0结束。 3.注意函数的返回值是size_t&#xff0c;是无符号的&#xff0c;加减是无法对比的。…

实用的云手机软件有哪些?高性价比云手机推荐

云手机不仅能模拟传统手机的功能&#xff0c;还能实现跨设备操作、数据同步等&#xff0c;极大地提升了用户的便利性。在众多云手机软件中&#xff0c;哪些软件表现出色呢&#xff1f;下面整理了一些功能强大、操作便捷且性能稳定的云手机APP&#xff0c;供大家参考选择。 1. O…

编程练习2 数据单元的变量替换

示例1: 1,2<A>00 示例2: 1,2<A>00,3<A>00 示例3: <B>12,1,2<B>1 示例4: <B<12,1 输出依次如下&#xff1a; #include<iostream> #include<vector> #include<string>using namespace std;/* 字符分割函数 将传入…

IIS中配置HTTPS证书的详细步骤

在IIS&#xff08;Internet Information Services&#xff09;中导入HTTPS证书的步骤主要包括下载证书、导入证书和为网站绑定证书几个环节。以下是详细的步骤说明&#xff1a; 一、下载SSL证书 首先&#xff0c;确保你已经从证书颁发机构&#xff08;CA&#xff09;下载了适…

三.python入门语法2

目录​​​​​​​ 1.控制结构 1.1.顺序结构 1.2.选择结构 习题 1.3.循环结构 1.3.1. while语句 1.3.2.for语句 1.3.3.循环嵌套 1.4.break语句 1.5.continue语句 1.6.pass语句 习题 1.控制结构 在学习控制结构之前我们通过一个故事来简单的描述一下控制结构&…

DAMODEL丹摩智算:LLama3.1部署与使用

文章目录 前言 一、LLaMA 3.1 的特点 二、LLaMA3.1的优势 三、LLaMA3.1部署流程 &#xff08;一&#xff09;创建实例 &#xff08;二&#xff09;通过JupyterLab登录实例 &#xff08;3&#xff09;部署LLaMA3.1 &#xff08;4&#xff09;使用教程 总结 前言 LLama3…

前端sm2国密加密时注意

如下方法&#xff1a; export function encrypt(str) {const sm2 require("sm-crypto").sm2;const cipherMode 1; // 1 - C1C3C2&#xff0c;0 - C1C2C3&#xff0c;默认为1//自定义密钥let publicKey "xxxxxxxx";//此处加密let a sm2.doEncrypt(str,…

【数字图像处理】简单粗暴介绍最近邻插值和双线性插值(附python实现)

目录 前言最近邻插值理论与公式部分代码部分优缺点 双线性插值理论与公式部分代码实现优缺点 双三次内插 前言 最近邻插值和双线性插值是两种常见的用于图像处理的方法&#xff0c;主要是用于实现图像的放大和缩小。本文中将以最为简单粗暴的方式介绍两种方法的原理&#xff0…

USB-CAN的使用说明

文章目录 前言一、USB-CAN模块二、产品特性三、引脚说明四、使用说明1.USB驱动安装2.CAN配置工具说明1. 菜单栏&#xff1a;2. 模式选择和收发数据显示&#xff1a;3. 数据发送4. 发送模式 五、AT指令设置参数六、硬件测试 前言 CAN总线协议&#xff1a;一种多主、串行通信协议…

淘客系统开发之卷轴模式系统源码功能分析

随着互联网技术的快速发展&#xff0c;电商行业不断创新&#xff0c;探索更加高效、有趣的用户参与机制。其中&#xff0c;卷轴模式作为一种新兴的商业模式&#xff0c;以其独特的积分兑换和任务系统&#xff0c;在淘客系统开发中得到了广泛应用。本文将从技术角度&#xff0c;…

汽车免拆诊断案例 | 2016 款宾利GT车仪表盘上的多个故障灯点亮

故障现象 一辆2016款宾利欧陆GT车&#xff0c;搭载CYCB发动机&#xff0c;累计行驶里程约为4.5万km。据车主反映&#xff0c;发动机偶尔无法起动&#xff0c;仪表盘上的多个故障灯点亮&#xff08;图1&#xff09;。此外&#xff0c;刮水器、电动车窗及空调等电器设备功能失效…

IDC 中国数据安全软件市场报告:顺应平台化趋势,打造综合性的数据安全平台

近期&#xff0c;IDC 发布了针对中国数据安全软件市场规模的预测报告——《中国数据安全软件市场预测&#xff0c;2024-2028》&#xff08;Doc# CHC51601524&#xff0c;2024年9月&#xff09;。该报告针对 2024-2028 年中国数据安全软件市场的规模、增长速度、驱动因素、阻碍因…

剧本杀全新体验:线上剧本杀发挥重要优势

剧本杀作为集游戏社交休闲为一体的消费方式&#xff0c;吸引了众多年轻人&#xff0c;让玩家在游戏中体验到各种角色&#xff0c;还能够满足社交需求。当下&#xff0c;剧本杀市场仍然在快速发展中&#xff01; 剧本杀市场创新 不过&#xff0c;在多年的发展中&#xff0c;剧…

智谱清影 - CogVideoX-2b-部署与使用

&#x1f351;个人主页&#xff1a;Jupiter. &#x1f680; 所属专栏&#xff1a;Linux从入门到进阶 欢迎大家点赞收藏评论&#x1f60a; 目录 体验地址&#xff1a;[丹摩DAMODEL官网](https://www.damodel.com/console/overview) CogVideoX 简介本篇将详细介绍使用丹摩服务器部…

C++20中头文件compare的使用

<compare>是C20中新增加的头文件&#xff0c;此头文件是language support库的一部分。它包括&#xff1a;concepts、classes、customization point objects、functions。 1.concepts&#xff1a;三向比较运算符<>&#xff0c;目的是简化比对对象的过程&#xff0c;…

ant design vue中带勾选表格报Tree missing follow keys: ‘undefined‘解决方法

1、这里一定要给columns和data-source设置key即可。 <div><a-table:row-selection"rowSelection":dataSource"tableList":columns"columns":scroll"{ x: 100% }":pagination"false":loading"loading"&g…