数据结构——并查集

一、并查集

并查集由一个整数型的数组和两个函数构成。数组pre[]记录了每个点的前导点是什么,函数find是查找,函数Union是合并。

一般来说,一个并查集对应三个操作:初始化+查找根结点函数+合并集合函数。

#define N 105
int pre[N];     //每个结点
int rank[N];    //树的高度
//初始化
int init(int n)     //对n个结点初始化
{
    for(int i = 0; i < n; i++){
        pre[i] = i;     //每个结点的上级都是自己
        rank[i] = 1;    //每个结点构成的树的高度为1
    }
}
 
int find_pre(int x)     //查找结点x的根结点
{
    if(pre[x] == x){        //递归出口:x的上级为x本身,即x为根结点
        return x;      
    }
    return find_pre(pre[x]);    //递归查找
}
 
//改进查找算法:完成路径压缩,将x的上级直接变为根结点,那么树的高度就会大大降低
int find_pre(int x)     //查找结点x的根结点
{
    if(pre[x] == x){        //递归出口:x的上级为x本身,即x为根结点
        return x;      
    }
    return pre[x] = find_pre(pre[x]);   //递归查找  此代码相当于 先找到根结点rootx,然后pre[x]=rootx
}
 
 
bool is_same(int x, int y)      //判断两个结点是否连通
{
    return find_pre(x) == find_pre(y);  //判断两个结点的根结点(亦称代表元)是否相同
}
 
void unite(int x,int y)
{
    int rootx, rooty;
    rootx = find_pre(x);
    rooty = find_pre(y);
    if(rootx == rooty){
        return ;
    }
    if(rank(rootx) > rank(rooty)){
        pre[rooty] = rootx;         //令y的根结点的上级为rootx
    }
    else{
        if(rank(rootx) == rank(rooty)){
            rank(rooty)++;
        }
        pre[rootx] = rooty;
    }
}

  

原文地址:https://www.cnblogs.com/yellowzunzhi/p/11048908.html