当前位置:   article > 正文

王道数据结构打卡(3)------并查集的应用_王道并查集

王道并查集

1.概论

定义:
   并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题(即所谓的并、查)。比如说,我们可以用并查集来判断一个森林中有几棵树、某个节点是否属于某棵树等。

主要构成:
   并查集主要由一个整型数组pre[ ]和两个函数union( )、join( )构成。数组 pre[ ] 记录了每个点的前驱节点是谁,函数 find(x) 用于查找指定节点 x 属于哪个集合,函数 join(x,y) 用于合并两个节点 x 和 y 。

作用:
  并查集的主要作用是求连通分支数(如果一个图中所有点都存在可达关系(直接或间接相连),则此图的连通分支数为1;如果此图有两大子图各自全部可达,则此图的连通分支数为2……)

2.定义一个并查集

  1. #define max 50
  2. int uset[max];

3.创立集合 

  1. void makeSet(int size)
  2. {
  3. for (int i = 1; i <= size; i++)
  4. {
  5. //各自为各自的代表
  6. uset[i] = i;
  7. }
  8. }

即:uset[1]=1,uset[2]=2,uset[3]=3,uset[4]=4,uset[5]=5,uset[6]=6。这意味着,uset[i]的朋友(父节点)是i自己。 

4.实现并查集的基本操作Union

    并查集的实现原理也比较简单,就是用树来表示一个集合,树的每个结点就是集合的一个元素,根节点就是集合的代表。以如下并查集为例。

1.合并(1,2,3,4),合并(5,6),分别以1和5作为代表

4.1.代码实现
  1. void unite(int x, int y)
  2. {
  3. //先找相对应的代表
  4. int x = find(x);
  5. int y = find(y);
  6. if (x == y)
  7. {
  8. return;
  9. }
  10. uset[x] = y;
  11. }

给出得到两个集合分别构建的合并过程

 合并2和1:分别找到自己的代表,都是自己2和1,显然2!=1,则uset[2]=1,这意味着,uset[2]的朋友是1;
合并3和2:分别找到自己的代表,都是自己3和2,显然3!=2,则uset[3]=2,这意味着3的朋友是2;
合并4和3:分别找到自己的代表,都是自己4和3,显然4!=3,则uset[4]=3,这意味着4的朋友是3;
这样(1,2,3,4)合并完成,此时可以发现它是一棵斜树。

同理,合并(5,6)就不再赘述。

现在,我们假设再合并(4,6)。

合并6和4:分别找到自己的代表5和1,显然5!=1,则uset[5]=1,这意味着5的朋友是3(1作为5的父节点)。

最终合并为同一个并查集结果如上 

5.查询

   find(x)其实就是查找x的代表是谁。查询采用递归的思想,直到代表是自己(访问到根结点),否则就一直找朋友的朋友...find(uset[i])

5.1.代码实现
  1. int find(int i){
  2. if(i==uset[i]){
  3. return i;
  4. }
  5. else
  6. return find(uset[i]);
  7. }

6.路径压缩

方法:查找时优化

     在每次查找时,令查找路径上的每个结点都指向根结点。

 

  1. int find(int i)
  2. {
  3. if (i == uset[i])
  4. {
  5. return i;
  6. }
  7. return uset[i] = find(uset[i]);//在第一次查找的时候 将结点直接连到跟
  8. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/909313
推荐阅读
相关标签
  

闽ICP备14008679号