Skip to content

Lec06 Union Find

一、概念

并查集主要由一个整型数组pre[ ]和两个函数find( )、join( )构成。  

数组 pre[ ] 记录了每个点的前驱节点是谁,函数 find(x) 用于查找指定节点 x 属于哪个集合,函数 join(x,y) 用于合并两个节点 x 和 y 。

二、实现

(1)pre数组

根节点的上级是自己  

(2)find函数:

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

(3)join函数:

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

三、优化

(1)路径优化find函数

思路:将x到根节点路径上的所有点的pre(上级)都设为根节点。

int find(int x)                    
{
    if(pre[x] == x) return x;      
    return pre[x] = find(pre[x]);  
}

(2)加权标记优化join函数

思路:所有节点都增设一个权值,用以表示该节点所在树中的高度。这样一来,在合并操作的时候就能通过这个权值的大小来决定谁当谁的上级

void union(int x,int y)
{
    x=find(x);                          //寻找 x的代表元
    y=find(y);                          //寻找 y的代表元
    if(x==y) return ;                   //如果 x和 y的代表元一致,说明他们共属同一集合,则不需要合并,直接返回;否则,执行下面的逻辑
    if(rank[x]>rank[y]) pre[y]=x;       //如果 x的高度大于 y,则令 y的上级为 x
    else                                
    {
        if(rank[x]==rank[y]) rank[y]++; //如果 x的高度和 y的高度相同,则令 y的高度加1
        pre[x]=y;                       //让 x的上级为 y
    }
}