让我们一起学习并查集吧

116 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第26天 点击查看活动详情

并查集的概念

  1. 并查集是一种维护集合的数据结构,其中,“并”指的是合并,“查”指的是查找,“集”指的是集合,综上所述,并查集支持以下两种功能:
    • 合并:将两个集合进行合并
    • 查找:判断两个元素是否在同一个集合
  2. 那么,并查集是用什么来实现的呢,其实就是数组
    • int father[N]
    • father[i]表示元素i的父亲节点,父亲节点也是这个集合内的元素。例如:father[1]=2,即元素1的父亲节点就是2,如果father[i]=i,那么元素i是该集合的根节点。但对同一集合来说只存在一个根节点,且将其作为所属集合的标识。

并查集的基本操作

总体来说,并查集的使用需要先初始化father数组,然后再根据个人需要进行查找和合并的操作。

初始化

一开始,每个元素都是一个独立的集合,因此设置father[i]=i,具体代码如下:

    for(int i=1;i<=n;i++){
         father[i]=i;
    }

查找

由于规定一个集合中只能存在一个根节点,因此,查找操作就是根据给定节点查找根节点的过程,实现的方式可以是递推或者递归,思路是一样的,也就是反复寻找父亲节点,直到找到根节点,也就是father[i]=i

递归代码如下:

//返回元素x所在集合的根节点
int findFather(int x){
     while(x!=father[x]){
          x=father[x];
     }
     return x;
}

合并

合并是将两个集合合并成一个集合,如果题目中给出两个元素,通常是将这两个元素所在集合进行合并。

那么如何实现呢? 我们通常先判断两个元素是否属于同一个集合,如果不属于同一个集合,则进行合并,合并的过程就是将其中一个集合的根节点的父节点指向另一个集合的根节点

合并代码如下:

void Union(int a,int b){
    int faA=findFather(a); //查找a的根节点
    int faB=findFather(b); //查找b的根节点
    if(faA!=faB)  father[faA]=faB; //不属于同一集合时进行合并
}