并查集详解

并查集支持查找一个元素所属的集合以及合并两个元素各自所属的集合等运算。它主要用于处理一些不相交的集合的合并问题。一些常见的用途有求连通子图、求最小生成树的Kruskal算法和求最近公共祖先(Least Common Ancestors, LCA)等。
并查集的数据结构记录了一组分离的动态集合 S={ S1,S2, …,Sk }。每个集合通过一个“代表”加以识别。“代表”即该集合中的某个元素,“代表”的选择是无所谓的。
并查集的基本操作有三个:
1、Make_set ( x ) :建立一个新的集合,其中仅有成员是x。
2、Union_set(x,y):将元素x和元素y所在集合合并,要求元素x和元素y 所在集合不相交,相交则不用合并。
3、Find(x):找到元素x所在的集合的“代表”。也可用来判断两个元素是否位于同一个集合,将两元素的“代表”判断是否是同一个就好。
并查集的实现可以用树来实现,每一个分离集合对应一棵树,成为分离集合树。整个并查集也就是分离集合森林。如图1所示,树中每个节点对应集合中的一个元素,根节点对应元素的“代表”。


这里写图片描述

                     图1、并查集的树表示

图中两棵树,分别对应两个集合,其中第一个集合为{a,b,c,d},代表元素是 a;第二个集合为 {e,f,g},代表元素是 e。
树中的节点代表集合中的元素,其中指针表示指向父节点地指针,根节点的指针指向自己,表示没有父节点。就这样不断向上找,就能找到根节点,即集合中的“代表”元素。
现在就能写出Make_set 和 Find 算法了。用一个足够长的数组来存储树中的节点。那么Make_set就可以创建出图2的森林,其中每个元素都是一个单元素集合,父节点都是自己。


这里写图片描述

                     图2、构造并查集初始化

那么Make_set的代码就可以写出来了。
const MAXSIZE=500;
int make[MAXSIZE];
void Make_set(int size)
{
    for(int i=1; i<=size; i++)
        make[i]=i;
}
接下来就是Find操作了。这里我用了递归的方法来求。也可以不用递归,用路径压缩。
路径压缩,就是在每次查找时,令查找路径上的每个节点都直接指向根节点,如图 3 所示。


这里写图片描述

                     图3、路径压缩

Find的算法如下
int Find(int x)
{
    if(x!=make[x])
        make[x]=Find(make[x]);
    return make[x];
}

int Find(int x)
{
    int p = x, t;
    while (make[p] != p) p = make[p];
    while (x != p) { t = make[x]; make[x] = p; x = t; }
    return x;
}
最后就是合并操作Union_set了。并查集的合并也很简单,就是将一个集合的树根指向另一个集合的树根。如图4所示


这里写图片描述

                     图4、并查集的合并

也可以按秩合并,该方法使用秩来表示树高度的上界,在合并时,将具有较小秩的树根指向具有较大秩的树根。为了保存秩,需要额外使用一个与make相同的数组保存秩,将初始值都保存为0
void Union_set(int x,int y)
{
    if((x=Find(x))==(y=Find(y)))
        return;
    if(rank[x]>rank[y])
        make[y]=x;
    else
    {
        make[x]=y;
        if(rank[x]==rank[y])
            rank[y]++;
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值