返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++并查集算法简单详解
  • 646
分享到

C++并查集算法简单详解

2024-04-02 19:04:59 646人浏览 独家记忆
摘要

目录1、并查集的初始化2、并查集的查找操作3、并查集的合并操作4、为什么要路径压缩?5、实现路径压缩总结1、并查集的初始化 并查集是用一个数组实现的。首先先定义一个数组: int f

1、并查集的初始化

并查集是用一个数组实现的。首先先定义一个数组:

int father[N];

father[i]表示元素i的父亲结点。

接下来进行初始化。一开始,每个元素都分别是独立的一个集合,父亲结点就是它自己,所以初始化时将所有father[i]等于i:

for(int i = 1; i <= N; i++){
    father[i] = i;
}

 这样,就将father数组初始化完毕。

2、并查集的查找操作

由于规定同一个集合中只存在一个根结点,因此查找操作,就是查找给定结点的根结点的过程。可以通过递推或递归来实现,思路都是一样的,都是反复寻找父亲结点,直到找到根结点为止。

递推代码:

//findFather函数返回元素x所在集合的根结点
int findFather(int x){
    while(x != father[x]){    //如果不是根结点,继续循环
        x = father[x];    //获得自己的父亲结点
    }
    return x;
}

上述代码中, while(x != father[x]),说明当x的父亲结点不等于本身时,也就是x不是根结点时就继续循环,因为父亲结点等于本身这个情况,只有在根结点才会出现。

递归代码:

int findFather(int x){
    if(x == father[x]) return x;    //如找到根结点,就返回根结点编号x
    else return findFather(father[x]); //否则,递归判断x的父亲结点是否是根结点
}

3、并查集的合并操作

合并,就是把两个集合合并成一个集合。实现过程是:先判断两个元素是否属于同一个集合,不属于同一个集合,就开始进行合并操作。判断两个元素是否属于同一个集合的具体思路,就是调用上面的findFather函数,分别查找两个元素所属集合的根结点,根结点不同,则两个元素不属于同一个集合。合并两个集合的具体思路,就是将其中一个集合的根结点的父亲指向另外一个集合的根结点即可。

合并操作的代码实现:(假设有两个集合,一个集合里有元素a,一个集合有元素b)

void UNIOn(int a, int b){
    //让一个集合的根结点的父亲指向另一个集合的根结点
    father(findFather(a)) = findFather(b); 
}

注意,合并操作之前,最好先判断下待合并的两个元素是否位于同一个集合。

4、为什么要路径压缩?

5、实现路径压缩

由于findFather函数目的就是查找根结点,所以,我们在查找结点的路径上直接将所有结点的父亲都指向根结点,查找的时候就不必一直回溯去寻找父亲了,查询的复杂度可以降为O(1)。

比如下面这张图:

观察图不难发现,上图中father[1] = 1,father[2] = 1,father[3] = 2,father[4] = 3。经过路径压缩,就变成下面这幅图:

相当于将所有结点的父亲都直接指向根结点,这就是路径压缩。

如何用代码实现路径压缩呢?以下是具体代码:

int findFather(int x){
    if(father[x] != x) father[x] = findFather(father[x]);
    return father[x];
}

 以上代码,实现了在查询获取根结点的同时,将路径进行压缩优化,代码虽然很短,但是很巧妙,下面解释下上述代码:

 if(father[x] != x),当所查找的元素x的父亲结点不是自己,也就是x不是根结点时,

findFather(father[x]),就继续递归查找父结点,直到找到根结点为止,

father[x] = findFather(father[x]),然后将找到的根结点直接赋给x的父亲结点。

这样就实现了路径压缩,即将结点的父亲直接指向根结点。

return father[x],返回查找到的根结点。

总结

到此这篇关于c++并查集算法简单详解的文章就介绍到这了,更多相关C++并查集算法内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++并查集算法简单详解

本文链接: https://lsjlt.com/news/139054.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++并查集算法简单详解
    目录1、并查集的初始化2、并查集的查找操作3、并查集的合并操作4、为什么要路径压缩?5、实现路径压缩总结1、并查集的初始化 并查集是用一个数组实现的。首先先定义一个数组: int f...
    99+
    2024-04-02
  • C#并查集(union-find)算法详解
    目录算法的主题思想:1. 动态连通性2. 定义问题3. quick-find算法实现算法分析4. quick-union算法实现森林表示算法分析5.加权 quick-uni...
    99+
    2024-04-02
  • C++如何实现并查集算法
    这篇文章主要介绍了C++如何实现并查集算法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1、并查集的初始化并查集是用一个数组实现的。首先先定义一个数组:int fa...
    99+
    2023-06-29
  • 详解C/C++高精度算法的简单实现
    目录前言一、基本原理二、辅助方法1、字符串转高精度2、整型转高精度3、比较4、打印三、算法实现1、加法2、减法3、乘法4、除法四、使用示例1、加法2、减法3、乘法4、除法总结前言 由...
    99+
    2022-12-15
    C++实现高精度算法 C++高精度算法 C语言 高精度算法
  • C++归并排序算法详解
    目录一.算法简介二.实现过程总结一.算法简介         归并排序算法的平均时间复杂度是O(nlo...
    99+
    2024-04-02
  • C语言并查集的非递归实现详解
    目录【算法分析】【算法代码】并查集压缩路径非递归写法参考文章总结【算法分析】 经典的递归实现的并查集,在数据规模过大时,可能会爆栈,因此有了并查集的非递归实现。核心代码如下: i...
    99+
    2024-04-02
  • Vue3diff算法的简单解刨
    目录性能比较前置与后置的预处理节点无序最长递增子序列上篇我们介绍了vue2中的双端diff算法的优势(相比于简单算法相同场景下移动DOM次数更少)。如今Vue3的势头正盛,在diff...
    99+
    2023-02-09
    Vue3 diff算法 Vue diff算法 Vue3 diff
  • java数据结构并查集详解
    目录一、概述二、实现2.1 Quick Find实现2.2 Quick Union实现三、优化3.1基于size的优化3.2基于rank优化3.2.1路径压缩(Path C...
    99+
    2024-04-02
  • Java实现并查集示例详解
    目录题目思路find实现join的实现整体代码 题目 题目背景 若某个家族人员过于庞大,要判断两个是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的两个人是否具有亲戚关...
    99+
    2024-04-02
  • Terraform集成简单Gitlab CI方案详解
    目录一 背景二 流程架构2.1 架构图2.2 流程三 预置条件四 配置4.1 Gitlab CI配置4.1.1 .gitlab.yaml4.1.2 环境配置4.2 Terraform...
    99+
    2024-04-02
  • 一文详解Vue3中简单diff算法的实现
    目录简单Diff算法减少DOM操作例子结论实现DOM复用与key的作用例子虚拟节点的key实现找到需要移动的元素探索节点顺序关系实现如何移动元素例子实现添加新元素例子实现移除不存在的...
    99+
    2024-04-02
  • 如何简单解释 MapReduce 算法
    今天就跟大家聊聊有关如何简单解释 MapReduce 算法,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。在Hackbright做导师期间,我被要求向技术背景有限的学生解释MapRed...
    99+
    2023-06-17
  • Matlab实现简单扩频语音水印算法详解
    目录一、实验背景1.实验目的2.实验环境3.原理简介二、基础知识1.PN序列2.时域到频域变换的原因3.三种时域到频域变换的区别三、算法源码1.PN产生函数2.隐藏算法3.提取算法4...
    99+
    2024-04-02
  • 超详细解析C++实现归并排序算法
    目录一、前言分治算法分治算法解题方法二、归并排序1.问题分析2.算法设计3.算法分析三、AC代码一、前言 分治算法 归并排序,其实就是一种分治算法 ,那么在了解归并排序之前,我们先来...
    99+
    2024-04-02
  • c/c++基础简单易懂的快速排序算法
    快速排序就是找一个基准,然后其左边要比他小,右边要比他大 int partition(int* a, int left, int right) { int pivot = le...
    99+
    2024-04-02
  • Java排序算法之归并排序简单实现
    算法描述:对于给定的一组记录,首先将每两个相邻的长度为1的子序列进行归并,得到 n/2(向上取整)个长度为2或1的有序子序列,再将其两两归并,反复执行此过程,直到得到一个有序序列。package sorting;public class M...
    99+
    2023-05-30
    java算法 归并排序 ava
  • C# 递归算法详解
    目录1)1、1、2、3、5、8.......用递归算法求第30位数的值?2)编写计算斐波那契(Fibonacci)数列的第n项函数fib(n)斐波那契数列为:0、1、1、2、3、……...
    99+
    2024-04-02
  • 详解spring-boot集成elasticsearch及其简单应用
    介绍记录将elasticsearch集成到spring boot的过程,以及一些简单的应用和helper类使用。接入方式使用spring-boot中的spring-data-elasticsearch,可以使用两种内置客户端接入节点客户端(...
    99+
    2023-05-31
    spring boot elasticsearch
  • 详解Navicat简单使用方法
    Navicat是一款用于数据库管理的工具,支持多种数据库系统,如MySQL、Oracle、SQL Server等。下面是Navicat的简单使用方法:1. 下载和安装Navicat:首先,从Navicat官方网站下载适用于你的操作系统的...
    99+
    2023-08-09
    Navicat
  • 详解Python中位运算的简单实现
    目录简介应用场景案例源码简介 程序中的数在计算机内存中都是以二进制的形式存在的,位运算就是直接对整数在内存中对应的二进制位进行操作,一般是将数字化为二进制数后进行操作。 应用场景 在...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作