《算法笔记》9.6 并查集

9.6 并查集

9.6.1 并查集的定义

并查集是一种维护集合的数据结构,他的名字中“并”、“查”、“集”分别取自Union(合并)、Find(查找)、Set(集合)。也就是说,并查集支持下面两个操作:

  • 合并:合并两个集合
  • 查找:判断两个元素是否在一个集合。

那么并查集用什么实现呢?其实就是用一个数组:

int father[N] ;

其中father[i]表示元素i的父亲结点,而父亲结点本身也是这个集合内的元素。如果fatjer[i]==i,则说明元素i是该集合的根结点。但对同一个集合来说只存在一个根节点,且将其作为所属集合的标识

例如
image.png

father[1] = 1 ; //1的父亲结点时自己,也就是说1是根结点
father[2] = 1 ; //2的父亲结点时1

9.6.2 并查集的基本操作

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

1. 初始化

一开始,每个元素都是独立的一个集合,因此令所有father[i] = i

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

2. 查找

由于规定同一个集合只存在一个根结点,因此查找操作就是对给定的结点寻找其根结点的过程。即反复寻找父亲结点,直到找到根结点。

递推方式

int findFather( int x ){
    while( x != father[x] ){   //不是根结点
          x = father[x] ;//获得自己的父亲节点
    }
    return x ;
}

递归方式

int findFather( int x ){
    if( x == father[x] ){
       return x ;
    }
    else{
       findFaher( father[x] ) ;
    }
    
}

3. 合并

合并是指把两个集合合并成一个集合,题目中一般给出两个元素,要求把这两个元素所在的集合合并。具体实现上一般实现判断两个元素是否数与同一个集合,只有当两个元素属于不同集合时才合并,而合并过程一般是把其中一个集合的根结点的父亲指向另一个集合的根结点。

image.png

void Union( int a , int b ){
    int faA = findFather(a) ;
    int faB = findFather(b) ;
    if( faA != faB ){
    	father[faA] = faB ; //合并
    }
}

最后说明并查集的一个性质。在合并的过程中,只对两个不同的集合进行合并,如果两个元素在相同的集合中,那么就不会对它们进行操作。这就保证了在同一个集合中一定不会产生环,即并查集产生的每一个集合都是一棵树。

9.6.3 路径压缩

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值