并查集概述

目录

并查集概述

并查集一般要处理的问题

并查集的实现方法

最后(求看)


并查集概述

并查集是一种树型的数据结构,由于处理一些不相交集合的合并及查询问题。

并查集思想是用一个数组表示了整片森林,树的根节点唯一是一个集合的标识,我们只要找到了某个元素的树确定它在哪个集合里。

如图(主干就是根节点,枝干就是子节点):


并查集一般要处理的问题

  1. 合并:将若干点合并到一个或多个集合(构成的一颗树或多棵树),将多个集合合并(多棵树合并为一棵树);
  2. 查询:询问某2个点是否在同一个集合中;
  3. 其他:计算共有多少个集合(多少棵树)。

并查集的实现方法

(1)举例说明

假设有如下8个点:1 2 3 4 5 6 7 8,假设如下两两的结点在一个集合中,通过并查集构建过程的模拟来看最终有几个集合,并理解并查集的构建过程和查询过程。

两两在一个集合中的节点有:

1 3

1 2

5 4

2 4

6 8

8 7

如图:

(2)数据结构的实现

实际操作时,我们会使用一个点来代表整个集合,就是一个元素的根节点(可以理解为父亲)。

实现方法:

我们要建立一个数组 f[ ] 表示一个并查集,f[i] 表示 i 的父节点。

  1. 初始化:一开始每一个节点都是一个集合,因此自己的父节点就是自己 f[i]=i (毕竟之后是要合并的)。
  2. 查询:每一个节点不断地寻找自己的父节点,若此时自己的父节点就是自己,那么该点为集合的根节点,随后返回该点。
  3. 合并:合并两个集合只需要合并两个集合的根节点,即f[RootA]=RootB,其中RootA,RootB是两个元素的根节点。
  4. 路径压缩:大多数情况下,在查询过程中只关心根节点是什么,并不关心这棵树的形态。因此我们可以再查询操作的时候将访问过的每个点都指向根节点,这样的方法叫做路径压缩。

如图:

初始化模板:

for(int i=1;i<=n;i++) f[i]=i;//只是模板,切勿直接运行

基本查询模板:求x的根:

int find(int x){
    return f[x]==x?x:find(f[x]);//三位运算符(不会的话,切勿使用!!!)
    /*
    if(f[x]==x) return x;
    else return f[x]=find(f[x]);
    (上面是三位运算符的正常版(新手用))
    */
}

路径压缩查询模板:

return f[x]==x?x:find(f[x]);//三位运算符(不会的话,切勿使用!!!)
/*
if(f[x]==x) return x;
else return f[x]=find(f[x]);
(上面是三位运算符的正常版(新手用))
*/

合并模板:先判断x和y是否在同一个集合:

void merge(int x,int y){
    int fx=find(x);
    int fy=find(y);
    if(fx!=fy) f[fx]=fy;
}

注意:合并与查询是亲兄弟,要一起用呦!!! 


最后(求看)

最后,现在我们就学完了并查集,并查集其实并不难,难的是要写太多字了!!!以上是作者本人自己总结。我还要说的是:看官们在学习后要趁热打铁做一份笔记呦(有利于加深理解)。

最后的最后:

我收到的评论有点少,希望看官们有时间能多评论指教一下我,谢谢了!!!

!!!

!!!

!!!

  • 14
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值