数据结构--并查集

1 并查集是一种树形数据结构,经常用于处理一些集合之间的操作。不同集合在并查集以不同的树来表示,一般每棵树的根节点会作为当前集合的代表元

想要查询两个集合是否在同一集合中,只需要比较两个元素所在集合的代表元是否相同即可

2 并查集的初始化

//假设一开始有n个元素,这些元素初始都是独立的,一开始构成n个集合,每个集合的代表元都是元素自己
const int maxn=100005;
int fa[maxn];//fa数组记录每个元素由谁代表
int sz[maxn];//sz数组代表每个集合元素个数
int dep[maxn];//dep数组记录每个集合的树深度
void initalize(int n){
    for(int i=1;i<=n;i++){
        fa[i]=i;
        sz[i]=dep[i]=1;
    }
}

3 集合合并

//先找到x,y对应的代表元
//将其中一个代表元的fa指向另外一个 
int findset(int x){
     if(x==fa[x])
         return x;
    fa[x]=findset(fa[x]);
    return fa[x];
}
void union(int x,int y){
    int fx=findset(x),fy=findset(y);
    if(fx==fy) return;
    fa[fx]=fy;
}

4 路径压缩:在查询代表元的过程中,把沿途的每个结点fa都设为集合代表元

int findset(int x){
     if(x==fa[x])
         return x;
    fa[x]=findset(fa[x]);
    return fa[x];
}
//简写
int findset(int x){
    return x==fa[x]? x:(fa=findset(fa[x]));
}

5 启发式合并

//在合并集合时,选择包含元素个数少的集合,将它合并到另外一个集合中,使需要改变代表元的元素尽量少
void union(int x,int y){
    int fx=findset(x),fy=findset(y);
    if(fx==fy) return;
    if(sz[fx]>sz[fy])
        swap(fx,fy);
    fa[fx]=fy;
    sz[fy]+=sz[fx];
}

6 按深度合并

//每次合并的时候,将深度比较小的合并到深度比较大的一方,并更新一下新集合的深度即可
void union(int x,int y){
    int fx=findset(x),fy=findset(y);
    if(fx==fy) return;
    if(dep[fx]>dep[fy]) swap(fx,fy);
    fa[fx]=fy;
    if(dep[fx]==dep[fy])
        dep[fy]++;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值