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

并查集

时间:2020-02-12 13:06:08      阅读:63      评论:0      收藏:0      [点我收藏+]

标签:com   数据   inf   info   信息   union   初始   基于   img   

并查集是一种用来管理元素分组情况的数据结构,可以高效的执行下面的操作:
1.查寻(find):查询元素a和b是否属于同一分组;
2.合并(union):将两个不同的分组合并为一个分组。
技术图片
注意并查集虽然可以进行合并操作,但是却无法进行分割操作。

并查集的结构

并查集使用树形结构实现,整个并查集由一颗或多棵树构成,每棵树代表一个分组。在并查集中,哪个节点是哪个节点的父亲以及树的形状等信息并不重要,整体形成一个树状结构才是关键。但是,在实际应用中,我们通常使用每个分组的根节点代表分组编号。

初始化

并查集初始状态是每个元素都属于自身的子集,即每个子集仅有一个元素。
技术图片

int fa[MAXN]; // 记录每个元素的父亲,初始化就是将每个元素的父亲设置为自身
void makeSet(int size) {
  for (int i = 1; i <= size; i++) 
    fa[i] = i;
}

查询分组

查找就是查看每个元素属于哪个分组,即通过该节点不断的查看自己的父亲,直到找到根节点。
技术图片

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

合并

合并就是将两个分组合并为一个分组,首先找到两个分组的根,然后从一个分组的根向另一个分组的根两边,这样,两棵树就成为了一颗树,也就把两个组合并为一个组了。
技术图片

void unionSet(int x, int y) {
  x = find(x); 
  y = find(y); 
  if(x != y)
    fa[x] = y;  
}

查询

查询两个元素是否属于同一个分组,我们仅需找到两个元素所在分组的根节点,判断是否为同一个即可。

优化

并查集采用了树状结构实现,如果树的高度越来越高,查询的效率也会越来越低。为了避免退化,我们可以考虑将高度较小的分组合并到高度较大的分组,下面就是考虑了高度的合并。
技术图片
此外,在中间节点没有影响的情况下,也可以通过路径压缩来减小树的高度。路径压缩就是一旦向上走到了一次根节点,就把这个点到父亲的边改为直接连向根。
技术图片

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

并查集

标签:com   数据   inf   info   信息   union   初始   基于   img   

原文地址:https://www.cnblogs.com/tomato1001/p/12298330.html

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