c++并查集生成方法

并查集查找的速度非常快,同时也能反映数据之间的关系。下面着重介绍并查集的生成方法

一开始先初始化,使得每一个节点的父亲都是他本身。然后要如何体现他们之间的关系呢?

这时就要写一个函数,这个函数接受两个参数a,b,然后找到a与b的父亲,令a的父亲=b的父亲(反之也可),这样a,b就在一起了,都归b或者a的父亲管。

但是,这样写会造成一个问题,树很容易退化成链表,使得效率大大降低,树层数太大,例如:

我要找到a的父亲,如果当前父亲的父亲不等于他自身,那么路径最差可能是这样的:

a->b的父亲->c的父亲......并不满意

压缩路径,防止退化:

我们要控制树每一层的节点数,压缩路径,使得每一层的节点数都大致相等,也就是让大树与小树合并一下,

如果a的高度小于b的高度,那么我们就让a的父亲等于b的父亲(这里与先前的有差别,先前的不管树的高度,a、b的父亲成为新树的父亲都可以),否则我们就让b的父亲等于a的父亲

#include <iostream>
#include<cstdio>
using namespace std;
//int fa[10005];
struct father
{
    int data;
    int weight;
    int h;
} fa[10005];
int init(int n)
{
    for(int i=1; i<=n; i++)
    {
        fa[i].data=i;//一开始根是自身
        fa[i].h=0;
        fa[i].weight=1;
    }
}
int find_set(int i)
{
    return fa[i].data==i?i:fa[i].data=find_set(fa[i].data);//返回根,将查询路径的根节点赋值为最终的根节点
}
int merge_set(int a,int b)
{
    int x=find_set(a);
    int y=find_set(b);
    if(x!=y)
    {
        if(fa[x].h<fa[y].h)
        {
            fa[x].data=fa[y].data;//代表把a的根指向b的根
            fa[y].weight+=fa[x].weight;//加权值
        }
        else
        {
            fa[y].data=fa[x].data;
            fa[x].weight+=fa[y].weight;
            if(fa[x].h==fa[y].h)
                fa[y].h++;
        }
    }
    return 1;
}
int main()
{
    freopen("in.txt","r",stdin);
    int n=0;
    cin>>n;
    init(n);
    merge_set(2,5);
    merge_set(2,4);
    for(int i=1;i<=n;i++)
    {
        cout<<fa[i].data<<" "<<fa[i].weight<<"\n";
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值