并查集详解及实现

news2024/9/24 15:24:00

看完这篇文章你将会知道:

什么是并查集?

并查集的原理。

并查集的JAVA实现。

并查集这部分内容还是很简单的,相信只要认真学,你正在上小学二年级的表弟都能学得会。(´▽`ʃ♡ƪ)

目录

一、啥是并查集?

二、并查集的原理

三、并查集的JAVA实现


一、啥是并查集?

并查集是就是一个数据结构。🫡

好吧,说了等于没说。

重来,重来:

一个数据结构的出现,就对应了一个对数据操作的需求。

那么并查集要解决的需求是什么呢?


并查集主要对集合进行操作。

如图,假设这三个集合非常的大(树的深度与节点数很很很很很大):

需求1:目前有一个X这个节点,我要知道,X这个节点到底是属于哪个集合的?

需求2:现在,我想把A为根节点的集合与C为根节点的集合进行合并得到一个新的集合。

需求3:目前有两个节点,分别是H和I,我想直到这两个节点是否属于同一个集合?

以上三个需求,并查集都能够实现,这也是并查集的主要功能。

二、并查集的原理

并查集的操作,刚才也看了,好神奇,但是他的原理很简单,底层就是一个1维整形数组

那么怎样的设计能把这些集合区分开来呢?

设计规则如下:

1、数组某一个元素的下标,对应着一个集合中一个元素的编号

2、数组某一个元素的值要么是负整数,要么是大于等于0的整数

3、如果数组某一个元素的值时负整数,这个元素的下标就是某一个集合的根节点编号

这个元素的元素值(负整数)的绝对值,就是这个集合的元素个数

4、如果数组某一个元素的值时大于等于0的整数,其元素值,是这个元素父节点的下标

其下标就是这个元素本身在自己集合的元素编号。

空讲不好理解,下面,小编还是用一个李子来给大家介绍

把下面这三个集合放入并查集:

第一步,初始化数组arr(并查集):

长度就是所有集合元素之和,每一个元素赋值-1:

现在这个数组就可以理解为有10个集合(含负数的元素个数),

每个集合的大小都是1(负数绝对值代表集合的个数)

第二步,把集合存放到并查集(具体实现文章后面讲,先看结果):

第一次看到,这个感觉很抽象,你看,这怎么判断谁是谁的集合?

其实很简单,下面是并查集的核心理解了哦:

如果要查看下面这个5元素,是那个集合的:

那就在数组arr中找到5这个下标,5下标对应的值是2,那就跟着蓝色箭头,走到2小标对应位置。

发现arr[2]<0,那么下标2就是5这个元素所属集合的根节点编号,而arr[2]的绝对值就是集合的大小。

神奇吧。

其他的查询和上面讲的一模一样,自己可以动手试试。

三、并查集的JAVA实现

实现并查集主要就是实现一下三个目标:

1、给定一个元素,获取此元素所属集合的根节点

2、合并两个元素所属的两个集合

3、判断两个元素,是否属于同一个集合

代码:

public class UnionFindSet {
    public int[] elem;//底层用数组维护

    public UnionFindSet(int n) {//构造方法,设置数组长度,默认每一个元素值-1(都是一个一个的集合,只有自己一个元素)
        this.elem = new int[n];
        Arrays.fill(elem,-1);
    }


    /**
     * 查找数据x 的根节点(属于那个集合)
     * @param x
     * @return 下标
     */

    public int findRoot(int x) {

        if(x < 0) {
            throw new IndexOutOfBoundsException("下标不合法,是负数");
        }

        while (elem[x] >= 0 ) {//当值是负数时,找到集合的根结点
            x = elem[x];//1  0
        }

        return x;
    }

    /**
     * 查询x1 和 x2 是不是同一个集合
     * @param x1
     * @param x2
     * @return
     */
    public boolean isSameUnionFindSet(int x1,int x2) {

        /**
         * 获取根节点下标
         * */
        int index1 = findRoot(x1);
        int index2 = findRoot(x2);
        if(index1 == index2) {
            return true;
        }
        return false;
    }

    /**
     * 这是合并操作
     * @param x1
     * @param x2
     */
    public void union(int x1,int x2) {//把x2合并到x1所属的集合

        /**
         * 获取根节点的下标
         * */
        int index1 = findRoot(x1);
        int index2 = findRoot(x2);

        if(index1 == index2) {//同一个元素,不需要合并
            return;
        }

        elem[index1] = elem[index1] + elem[index2];
        elem[index2] = index1;
    }

    public int getCount() {//获取到底有几个集合
        int count = 0;
        for (int x : elem) {
            if(x <  0) {
                count++;
            }
        }
        return count;
    }



}

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

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

相关文章

什么样的展馆场馆才是科技满满?就差一张智慧场馆大屏

随着科技的飞速发展&#xff0c;传统的场馆展示方式已经无法满足现代人对信息获取和体验的需求。智慧场馆大屏作为一种新型的展示方式&#xff0c;应运而生。它将高清大屏显示技术、智能交互技术、数据分析技术等融为一体&#xff0c;为观众带来更加丰富、生动的展示体验。 一…

跨境热销爆款货源哪里找?选品工具不能少

通常&#xff0c;跨境电商找热销货源的几种方法&#xff1a; 1、使用Google Trends、亚马逊销售排行等来追踪和分析当前的市场趋势和热门产品&#xff1b; 2、关注社交媒体、行业论坛和博客等渠道&#xff0c;以获取最新的市场信息和消费者反馈&#xff1b; 3、在主流的跨境…

python-编写函数判断一个三位数是否为水仙花数。

【问题描述】要求编写函数isflower(n)判断一个三位数n是否为水仙花数,如果是&#xff0c;则返回True&#xff0c;否则返回False。在主程序中要求调用该函数并输出三位数中所有的水仙花数。所谓"水仙花数"是指一个3位数&#xff0c;其各位数字立方和等于该数本身。例如…

【动态规划】零基础解决路径问题(C++)

目录 62.路径问题 解法&#xff08;动态规划&#xff09;&#xff1a; 1. 状态表⽰&#xff1a; 2. 状态转移⽅程&#xff1a; 3. 初始化&#xff1a; 4. 填表顺序&#xff1a; 5. 返回值&#xff1a; 不同路径2.0 解法&#xff08;动态规划&#xff09;&#xff1a; …

MySQL——存储过程,触发器

BaiduComate: # 问题1&#xff1a; # 问题1&#xff1a; 帮我创建两个表student与score表&#xff0c;要求student表有id&#xff0c;createDate&#xff0c;userName&#xff0c;phone&#xff0c;age&#xff0c;sex&#xff0c;introduce&#xff0c; 要求score表有id&…

迷你手持小风扇哪个牌子质量好点?这五款迷你手持小风扇不要错过

随着空调的普及&#xff0c;我们对夏日热浪的抵抗力逐渐减弱。当从凉爽的空调屋步入闷热的户外、拥挤的交通工具或公共场所时&#xff0c;如何抵御热浪的侵袭成为大众关注的焦点。在这样的背景下&#xff0c;迷你手持小风扇凭借其便携性和即时降温功能&#xff0c;成为众多人的…

和可被k整除的子数组 ---- 前缀和

题目链接 题目: 分析: 补充知识 1. 同余定理: (a-b) % p 0即a-b能被p整除, > a % p b % p 2. c, java中 [负数 % 正数] 的结果是负数, 想要得到正确结果 > (a%pp)%p这道题和<和为k的子数组>类似, 利用前缀和的思想, 计算以i结尾的所有子数组, 前缀和为sum[i] …

炸裂!AI五分钟模仿爆款IP故事,涨粉速度太绝了!

‍ ‍大家好&#xff0c;我是向阳。 今天我要分享一个利用AI技术模仿爆款账号的小技巧&#xff0c;帮助大家迅速增加粉丝。这个方法简单实用&#xff0c;尤其适用于副业和本地生活领域。接下来&#xff0c;我将为大家详细讲解操作步骤。让我们开始吧。 副业赚钱&#xff1a;模…

QT 程序缺少API-开头文件

无法启动此程序&#xff0c;因为计算机中丢失api-ms-win-core-rtlsupport-11-2-0dl。尝试重新安装该程序以解决此问题 因为打包QT程序经常去到的别的电脑会缺少系统的MFC开头 msvcp 的库所以&#xff0c;QT自带的VC安装包体验不够好所以都是自己本地复制一套进行打包。。 有部…

LVDS与IDELAY

摘要&#xff1a;LVDS&#xff08;Low-Voltage Differential Signaling&#xff09;低电压差分信号&#xff0c;是一种低功耗、低误码率、低串扰和低辐射的差分信号技术&#xff1b;LVDS会被经常使用到&#xff0c;使用的过程中难免会碰到时序问题&#xff0c;需要借助IDELAY进…

在看代码的时候,vscode使用书签快速跳转到想看的代码

安装bookmarks 重启vscode之后&#xff0c;摁F1 搜搜索“书签”&#xff0c;更改自己需要的快捷键&#xff0c;我这里更改了三个

生命在于学习——Python人工智能原理(1.2)

一、人工智能的基本知识 6、新一代人工智能驱动因素 &#xff08;1&#xff09;数据量爆发性增长。 &#xff08;2&#xff09;计算能力大幅提升 &#xff08;3&#xff09;深度学习等算法发展 &#xff08;4&#xff09;移动AI创新应用牵引 7、人工智能关键技术 &#x…

降价!免费!AI大模型开启价格战,企业如何“薅”出绿色财富?

近期&#xff0c;国内大模型技术供应商之间的价格战&#xff0c;使得这项原本成本较高的技术变得更加亲民&#xff0c;极大降低了企业的技术采用门槛。这不仅为企业提供了经济实惠的技术解决方案&#xff0c;更为他们的绿色低碳转型之路带来了新的机遇。 随着全球气候变化问题…

认知觉醒:情绪绝对是财富的拦路虎……

认知觉醒 无论是投资还是做生意&#xff0c;跟随大众情绪就一定会亏损&#xff0c;老百姓没有是非认知&#xff0c;只有好恶&#xff0c;所以就很容易被人操控情绪。随便一个社会热点事件&#xff0c;就比如最近的涂磊事件、郭有才事件&#xff0c;打开视频的评论区&#xff0…

GaussDB数据库的备份与恢复

1.逻辑备份-gs_dump gs_dump是一款用于导出数据库相关信息的工具&#xff0c;支持导出完整一致的数据库对象&#xff08;数据库、模式、表、视图等&#xff09;数据&#xff0c;同时不影响用户对数据库的正常访问。 备份sql语句 gs_dump是openGauss用于导出数据库相关信息的工…

吴恩达2022机器学习专项课程C2W2:2.17 TensorFlow实现 2.18 训练细节

这里写目录标题 本周任务TensorFlow训练神经网络模型的简要过程训练模型的三个步骤1.自行训练逻辑回归模型2.TensorFlow训练神经网络模型 TensorFlow训练神经网络模型的代码含义1.定义模型2.指定损失函数和成本函数3.最小化成本函数 总结QuizQuiz1Quiz2 本周任务 神经网络如何…

ZeroTier+Nomachine远程

目录 前述&#xff1a;一、Zero二、Nomachine 前述&#xff1a; 需要远程控制时&#xff0c;服务端与客户端都必须下载这两个软件&#xff01;远程主机&#xff08;被控制的主机&#xff09;和远程客户端&#xff08;控制主机的用户&#xff09;都必须具有网络连接&#xff0c;…

代码随想录算法训练营第四十一天|动态规划理论基础、509. 斐波那契数列、70. 爬楼梯、746. 使用最小花费爬楼梯

动态规划理论基础 什么是动态规划 动态规划&#xff0c;英文&#xff1a;Dynamic Programming&#xff0c;简称DP&#xff0c;如果某一问题有很多重叠子问题&#xff0c;使用动态规划是最有效的。 所以动态规划中每一个状态一定是由上一个状态推导出来的&#xff0c;这一点就…

C语言常用字符串处理函数

C语言中包含了很多对字符串处理的函数,要使用这些函数&#xff0c; 首先需要导入头文件#include <string.h> 1. strlen() -- 计算字符串长度 原型: size_t strlen(char const *string); 例: char *str "abcde"; size_t len strlen(str); // 结果为…