c++入门必学算法 并查集

article/2025/8/27 0:02:45

一、什么是并查集

并查集其实就是实现一个类似朋友圈的功能,朋友的朋友是朋友,朋友的朋友的朋友也是朋友,即只要有关系一些人就合并成为一个朋友圈。

并查集可以实现查询两个人是否是朋友,查询朋友圈的个数

二、并查集的原理

并查集原理和构图是类似的,但是构图每次查询的速度是 O(n) ,慢得离谱,此时查询复杂为 O(1) 的并查集算法就出现了

我们定义一个数组 f[n] ,其下标表示点,他的值表示和其它点有关系,例如 f[1] = 4,即 1 号和 4 号是朋友,如果 f[4] = 6,即说明 4 号和 6 号是朋友。

那么我们如何知道 1 号和 6 号是朋友呢?假如 f[6] = 6,那么就说明 6 的后面没有朋友了,此时我们通过 f[1] 可以找到 4 ,通过 f[4] 可以找到 6,通过 f[6] 仍然找到 6,那么这个朋友链的结尾就是6,而 f[6] = 6,仍然找到 6,那么这个朋友链的结尾也是6,那么就说明 1 号和 6 号是朋友。

我们应该能理解,我们都是通过朋友链最后一个朋友判断两个人是不是朋友的,例如:
f[1] = 4,f[4] = 6,f[6] = 9,f[9] = 5,f[5] = 5;
那么就有关系链1 — 4 — 6 — 9 — 5
无论是1、4、6、9、5中哪个数,只要顺着链往下找,最后肯定都是找到 5 的,那么我们就可以判断两个数是不是朋友

示例代码:

#include<iostream>
using namespace std;
int f[100010]; 
int find(int a){if(f[a]!=a)return find(f[a]);//如果当前节点不是末尾节点,继续往下找return a;
}
int main(){for(int i=0;i<100010;i++){//我们需要初始化f[i]的值都等于i f[i]=i;}
}

三、并查集的优化

没有优化的并查集查询的时间复杂度是O(n),并没有达到我们想要的效果,那么我们该如何优化呢?

可以看到,一条朋友链如下
1 — 4 — 6 — 9 — 5
我们查找 1 时,总是要经过 4、6、9 这些没用的中间关系,我们需要尝试去掉这些冗余的查询,将关系链变为如下格式:
在这里插入图片描述

实际上也就是将原来的:
f[1] = 4,f[4] = 6,f[6] = 9,f[9] = 5,f[5] = 5;
转换为:
f[1] = 5,f[4] = 5,f[6] = 5,f[9] = 5,f[5] = 5;

我们只要在原来的递归查找里将查找到的值赋给当前点就好了

示例代码:

#include<iostream>
using namespace std;
int f[100010]; 
int find(int a){if(f[a]!=a)return f[a]=find(f[a]);//如果当前节点不是末尾节点,继续往下找,并且将当前点的值更新为找到的结果 return a;
}
int main(){for(int i=0;i<100010;i++){//我们需要初始化f[i]的值都等于i f[i]=i;}
}

四、并查集的基本使用

1、添加关系:f[find(a)] = find(b)
2、查询关系find(a)==find(b),如果为真,即有关系,否则没有关系
3、查询关系集合的个数,有多少个末尾节点就有多少个集合,即 f[a]==a 的数

下面模拟这个图的集合:
在这里插入图片描述

有边(1,2)、(2,8)、(8,4)、(5,9)、(3,10)、(10,6)

示例代码:

#include<iostream>
using namespace std;
int f[100010]; 
int find(int a){if(f[a]!=a)return f[a]=find(f[a]);//如果当前节点不是末尾节点,继续往下找,并且将当前点的值更新为找到的结果 return a;
}
int main(){for(int i=0;i<100010;i++){//我们需要初始化f[i]的值都等于i f[i]=i;}//	构造并查集 f[find(1)]=find(2);f[find(2)]=find(8);f[find(8)]=find(4);f[find(5)]=find(9);f[find(3)]=find(10);f[find(10)]=find(6);int n=0;
//	查询集合个数for(int i=1;i<=10;i++){if(f[i]==i)n++;} cout<<"有"<<n<<"个集合"<<endl; //	查询关系 int a,b;while(1){cout<<"请输入1到10的两个数:"<<endl; cin>>a>>b;if(find(a)==find(b)){cout<<a<<"和"<<b<<"有关系"<<endl; }else{cout<<a<<"和"<<b<<"没有关系"<<endl; }cout<<endl;}}

运行结果:

4个集合
请输入110的两个数:
2 4
24有关系请输入110的两个数:
1 5
15没有关系请输入110的两个数:
5 9
59有关系请输入110的两个数:

五、并查集模板

#include<iostream>
using namespace std;
const int N=100000;
int f[N+10]; 
int find(int a){//查询函数 if(f[a]!=a)return f[a]=find(f[a]);return a;
}void add(int a,int b){//添加关系 f[find(a)]=find(b);
}int check(int a,int b){//查询关系 return find(a)==find(b);
}int cnt(){//查询集合个数 int n=0;for(int i=1;i<=N;i++){if(f[i]==i)n++;} return n;
}void init(){//初始化 for(int i=0;i<100010;i++){f[i]=i;}
}int main(){init();}

并查集的基本使用就到这里了

感谢观看,点个赞吧!


http://chatgpt.dhexx.cn/article/Vv7S5kpL.shtml

相关文章

并查集的查询与合并详解

文章目录 一、并查集的概念 二、并查集的实现 2、1 并查集不同集合&#xff08;树&#xff09;的形成 2、2 find&#xff08;&#xff09;函数找一个元素集合的编号&#xff08;元素所属于树的祖宗&#xff09; 2、3 合并两个不同集合&#xff08;合并两棵不同的树&#xff09…

并查集实现及其应用

先看看度娘给出的定义吧&#xff1a; 并查集&#xff0c;在一些有N个元素的集合应用问题中&#xff0c;我们通常是在开始时让每个元素构成一个单元素的集合&#xff0c;然后按一定顺序将属于同一组的元素所在的集合合并&#xff0c;其间要反复查找一个元素在哪个集合中。这一类…

超级简单并查集详解

一、概述 并查集&#xff0c;在一些有N个元素的集合应用问题中&#xff0c;我们通常是在开始时让每个元素构成一个单元素的集合&#xff0c;然后按一定顺序将属于同一组的元素所在的集合合并&#xff0c;其间要反复查找一个元素在哪个集合中。 其实说白了大部分还是用于寻找两…

并查集(java)

介绍 &#xff1a; 并查集属于数据结构的一种 是高等数据结构最基础的一部分&#xff0c;主要分为普通并查集 种类并查集以及带权并查集。它是一种用于管理元素所属集合的数据结构&#xff0c;这里的集合我们可以理解为一颗数 每个元素都是树上的有一个分叉&#xff0c;顺着分叉…

C++并查集

文章目录 并查集的原理并查集的实现代码并查集的典型应用 并查集的原理 在一些应用问题中&#xff0c;需要将n个不同的元素划分成一些不相交的集合。开始时&#xff0c;每个元素自成一个单元素集合&#xff0c;然后按一定的规律将归于同一组元素的集合合并。在此过程中要反复用…

c++并查集(详细总结)

老话重谈&#xff0c;先看定义 并查集是一种树型的数据结构&#xff0c;用于处理一些不相交集合&#xff08;disjoint sets&#xff09;的合并及查询问题。常常在使用中以森林来表示。 首先得明白一些概念&#xff1a; 什么是树&#xff0c;什么是森林&#xff08;由树组成的叫…

Java——并查集

概念 当我们将多个元素分配到不同的集合中&#xff0c;这些集合有的是相关的&#xff0c;有的是不相关的。并查集就是用来查找两个元素是否在同一个集合中的 其主要实现方式是&#xff1a;将所有的元素以下标的形式存储在数组中。例如一共有十个人&#xff0c;那么就将这些人…

并查集Python版

以下来自于leetcode 使用数据结构&#xff1a;并查集 思路&#xff1a;由于相等关系具有传递性&#xff0c;所有相等的变量属于同一个集合&#xff1b;只关心连通性&#xff0c;不关心距离&#xff0c;因此很容易想到并查集。&#xff08;很容易嘛&#xff0c;反正我想不到&am…

并查集详解

文章目录 并查集一、简介1.定义2. 并查集的实现与优化 二、练习1.合并集合2.连通块中点的数量3. 食物链 三、总结 并查集 一、简介 1.定义 并查集是一种树型的数据结构&#xff0c;用于处理一些不相交集合的合并及查询问题&#xff08;即所谓的并、查&#xff09;。比如说&am…

带权并查集

带权并查集需要先理解一般的并查集&#xff0c;不明白的可自行先搜索有关内容 一般的并查集主要记录节点之间的链接关系&#xff0c;而没有其他的具体的信息&#xff0c;仅仅代表某个节点与其父节点之间存在联系&#xff0c;它多用来判断图的连通性&#xff0c;如下图所示&…

并查集,不就一并和一查?

什么是并查集 并查集这种数据结构&#xff0c;可能出现的频率不是那么高&#xff0c;但是还会经常性的见到&#xff0c;其理解学习起来非常容易&#xff0c;通过本文&#xff0c;一定能够轻轻松松搞定并查集&#xff01; 对于一种数据结构&#xff0c;肯定是有自己的应用场景和…

数据结构——并查集

并查集是一种数据结构&#xff0c;是树的一种应用&#xff0c;用于处理一些不交集&#xff08;一系列没有重复元素的集合&#xff09;的合并以及查询问题。并查集支持如下操作&#xff1a; 查询&#xff1a;查询某个元素属于哪个集合&#xff0c;通常是返回集合内的一个“代表…

并查集详解(C/C++)

并查集算法详解&#xff08;C&#xff09; 并查集基础并查集是什么&#xff1f;并查集的作用是什么&#xff1f;并查集的结构合并查询 代码实现优化1&#xff1a;避免退化&#xff08;按秩合并&#xff09;代码优化 优化2&#xff1a;路径压缩代码优化 最终代码实现复杂度分析经…

并查集及其应用

并查集的基本操作: 1.合并两个集合 2.查询两个元素的祖宗节点 扩展: 1.记录每个集合的大小 将集合大小绑定到代表元素节点上 就是并查集的思想 (不是每个元素都是正确的 但是代表元素是正确的) 2.记录每个点到根节点的距离 绑定到每个元素身上 因为每个元素到根节点的距离…

并查集(Union-Find) (图文详解)

文章目录 并查集基础知识定义C实现优化 精选算法题(Java实现)实现并查集交换字符串中的元素最长连续序列 - 字节面试常考连通网络的操作次数最大岛屿数量 (三种解法)省份数量冗余连接冗余连接Ⅱ情侣牵手(困难)移除最多的同行或同列石头等式方程的可满足性 结语 并查集基础知识 …

什么是 “并查集” ?

导语&#xff1a;并查集是一种精巧的算法&#xff0c;本身并不难理解&#xff0c;却很常用&#xff0c;在许多场景下都能找到并查集的身影。 本文作者封承成&#xff0c;年仅12岁&#xff0c;非常感谢他的投稿。 并查集是什么 并查集&#xff0c;是一种判断“远房亲戚”的算法。…

并查集(Disjoint Set)

目录 ❤️什么是并查集&#xff1f; &#x1f3b6;实现方法1 &#x1f414;实现方法2 &#x1f383;题目1 ❤️什么是并查集&#xff1f; 并查集是一种数据结构&#xff0c;用于处理一些不交集&#xff08;Disjoint sets&#xff0c;一系列没有重复元素的集合&#xff09;的…

并查集

参考 https://www.cnblogs.com/asdfknjhu/p/12515480.html https://www.bilibili.com/video/BV13t411v7Fs?p3 https://leetcode-cn.com/problems/number-of-provinces/solution/python-duo-tu-xiang-jie-bing-cha-ji-by-m-vjdr/ 一、基本概念 并查集是一种数据结构 并查集这…

并查集(详细解释+完整C语言代码)

目录 1概论 2.树的表现形式 3.代码实现 3.1创立集合 3.2合并 3.3查询 3.4路径压缩 第一个方法&#xff1a;查找时优化 第二个方法&#xff1a;合并时优化&#xff08;加权标记法&#xff09; 4.完整代码 4.1优化前 4.2优化后 1概论 并查集是一种十分精巧且实用的树形…

时间序列预测的一般步骤

一、ARIMA模型概述 ​​ ARMA模型就是AR和MA的简单结合&#xff0c;同时包含了历史数值项和错误项。由于AR和MA模型都对时间序列有平稳性要求&#xff0c;ARMA模型也存在这个限制&#xff0c;因此我们将其拓展到ARIMA模型&#xff0c;其可以解决非平稳性问题。引入的差分概念是…