并查集——基础篇

前言

        好久不见,作者连续两个星期准备比赛,终于比完了,接着来更新c++的内容


什么是并查集

        

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

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

        1.并查集要一般处理的问题

        (1)合并:将若干个点合并到一个或多个集合(构成一棵树或多棵树),将多个集合合并(多棵树合并为一棵树);

        (2)查询:询问某2个点是否在同一个集合里(查询);

        (3)其他:计算共有几个集合(几棵树);

        2.并查集的实现方法

        (1)举例说明

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

        两辆在一个集合中的结点有:

        1  3

        1  2

        5  4

        2  4

        6  8

        8  7

        (2)数据结构的实现

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

        实现方法

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

        (1)初始化:每一个点都是一个集合,因此自己的父节点就是自己 fa[i]=i

        (2)查询:每一个节点不断寻找自己的父节点,若此时自己的父节点就是自己,那么该点为集合的根结点,返回该点。

        (3)合并:合并两个集合只需要合并两个集合的根结点,即 fa[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]);
}
//路径压缩查询模板:
f[x]==x?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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值