图论算法----并查集中的启发式合并

一、启发式合并的算法原理

一听这名字,感觉好高大上,实际上很简单。

由于路径压缩在有些题目会损失海量的信息,用暴力并查集又要超时,所以就出现了启发式合并算法。

之前讲过并查集的大部分时间都浪费在了find()函数上,于是就对find()函数进行了优化,其实启发式合并算法可以使find()函数的时间复杂度控制在O(logn)左右。

并查集是一种树型的数据结构,而树也有它的深度,如果我们把一棵深度大的树的根节点接在了一棵深度小的树上,那么整棵树的深度为那一棵深度大的树的深度+1,如果我们把一棵深度小的树的根节点接在了一棵深度大的树上,则整棵树的深度为max(深度小的树的深度+1,深度大的树的深度)。这就是启发式合并的原理。

如果感觉很难理解,看下面的图就知道了。

1、有两棵树,一棵高度为3,一棵高度为5。


2、如果是普通的合并,就会造成高度为6的树。


3、如果是启发式合并,最后的树的的高度为5。


好了,启发式合并的原理讲得差不多了,可以发代码了,记住height[]数组初始化为1。


二、启发式合并的代码

void qfsunion(int x,int y)
{
    int a=find(x);
    int b=find(y);
    if(height[a]>height[b])
        fa[b]=a;
    else if(height[a]<height[b])
        fa[a]=b;
    else{
        fa[a]=b;
        height[b]++;
    }
}
配套一个find()函数:

int find(x)
{
     while(fa[x]!=0)
         x=fa[x];
      return x;
}



三、启发式合并与路径压缩之间的问题

这时有人会问了:为什么find()函数不用路径压缩呢?

原因很简单,因为有了路径压缩,启发式合并算法就没有保护数据的效果了。

可以看出,启发式合并+路径压缩并不是最好的选择,而且路径压缩在主动改变树的高度,但是height数组的值不能同步改变,有可能让启发式合并出错。

  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值