Loading

并查集的原理及实现

定义

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

代码实现

在并查集结构中,用一个pre[]数组来存储当前结点的父亲结点,有两个函数,found()函数用来寻找根结点,join()函数用来合并两个并查集。

初始化

把每个结点的父亲结点初始化为自己

void init()
{
    for(int i=0;i<n;i++)
        pre[i]=i;
}

found()函数

寻找当前结点的根结点

int found(int x)
{
    int r=x;
    while(r!=pre[r])
    {
        r=pre[r];
    }
    int i=x,j;
    while(i!=r)//路径压缩
    {
        j=pre[i];
        pre[i]=r;
        i=j;
    }
    return r;
}

路径压缩是防止并查集查询的时间复杂度退化为O(n),形成一条链,因此把路径上的父亲结点全部设为根结点
同时路径压缩也可以通过递归来实现

int found(int x)
{
    return pre[x]=(x==pre[x]?x:found(pre[x]));
}

join()函数

用来合并两个并查集,先判定两个结点是否属于一个并查集,如果不属于,则将x根结点的父亲结点设为y的根结点

void join(int x,int y)
{
    int a=find(x);
    int b=find(y);
    if(a!=b)
    {
        pre[a]=b;
    }
}

除了使用路径压缩来防止并查集退化外,还可以使用启发式优化,在每次合并时将层数少的树合并到层数多的树上。

posted @ 2018-07-31 12:59  天使的羽翼  阅读(1277)  评论(0编辑  收藏  举报