码迷,mamicode.com
首页 > 其他好文 > 详细

并查集的原理及实现

时间:2018-07-31 15:32:38      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:时间复杂度   查询   自己   集合   路径   一个   []   存储   递归   

一、定义

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

二、代码实现

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


 

初始化

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

1 void init()
2 {
3     for(int i=0;i<n;i++)
4         pre[i]=i;
5 }

 

found()函数

  寻找当前结点的根结点

 

 1 int found(int x)
 2 {
 3     int r=x;
 4     while(r!=pre[r])
 5     {
 6         r=pre[r];
 7     }
 8     int i=x,j;
 9     while(i!=r)//路径压缩
10     {
11         j=pre[i];
12         pre[i]=r;
13         i=j;
14     }
15     return r;
16 }

 

路径压缩是防止并查集查询的时间复杂度退化为O(n),形成一条链,因此把路径上的父亲结点全部设为根结点

同时路径压缩也可以通过递归来实现

1 int found(int x)
2 {
3     return pre[x]=(x==pre[x]?x:found(pre[x]));
4 }

join()函数

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

1 void join(int x,int y)
2 {
3     int a=find(x);
4     int b=find(y);
5     if(a!=b)
6     {
7         pre[a]=b;
8     }
9 }

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

 

  

并查集的原理及实现

标签:时间复杂度   查询   自己   集合   路径   一个   []   存储   递归   

原文地址:https://www.cnblogs.com/yanchaoyi/p/9395286.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!