并查集小结

举报
Linux猿 发表于 2021/08/06 00:04:13 2021/08/06
【摘要】 并查集(Union-find Sets):           先说一下这几天研究并查集的感悟吧!以前学习并查集感觉没什么不就是一个查询+合并吗? 开始几道题也很简单很快水之,谁知到后面遇到深层次的就不是如何是好。顿时感觉并查集好强大。    &nbsp...

并查集(Union-find Sets):

          先说一下这几天研究并查集的感悟吧!以前学习并查集感觉没什么不就是一个查询+合并吗? 开始几道题也很简单很快水之,谁知到后面遇到深层次的就不是如何是好。顿时感觉并查集好强大。

         定义:并查集是一种树型的数据结构,树中的每一个节点代表一个元素,用于处理一些不相交集合的合并与查询问题。应用:求无向图的连通分量个数、最小公共祖先、带限制的作业排序、Kruskal 算法求最小生树.

三种基本操作:

                       1) 初始化: init ( n )  建立一个有n个元素的并查集,使每一个元素指向自身                        

                 . 

 

 

 代码:

   
  1. const int MX =100006 ;
  2. struct node
  3. {
  4. int parent,relation ;
  5. }T[MX] ;
  6. void init(int n)
  7. {
  8. for(int i=1 ;i<=n ;i++)
  9. {
  10. T[i].parent=i ;
  11. T[i].relation=0 ;// 表示此节点与根节点的关系,如果只是单纯的并查集这里可以省略
  12. }
  13. }

                       2) 查找   : find( x )   查找 x 的祖先.(这样可以判断两个元素是否在同一个集合中)

代码:

   
  1. int find(int x)
  2. {
  3. return T[x].parent==x ? x : T[x].parent=find(T[x].parent) ;// 路径压缩
  4. }
                          3)合并    :union_find( x , y )  合并 x 与 y 所在的集合.

代码:

   
  1. void union_find(int x,int y)
  2. {
  3. int ax=find(x) ;
  4. int ay=find(y) ;// 寻找根节点
  5. if(ax!=ay)
  6. T[ax].parent=ay ;
  7. }

并查集优化:
                   1) 按秩合并(启发式合并):这种方法按照两个树的高度合并,将高度小的合并到高度大的上。
代码:

   
  1. void union_find(int x,int y)
  2. {
  3. int ax=find(x) ;
  4. int ay=find(y) ;// 寻找根节点
  5. if(ax!=ay)
  6. {
  7. if(T[ax].rank<T[ay].rank)// 比较树的高度
  8. T[ax].parent=ay ;
  9. else
  10. {
  11. T[ay].parent=ax ;
  12. if(T[ax].rank==T[ay].rank)
  13. T[ax].rank++ ;
  14. }
  15. }
  16. }

                2)按集合中元素的个数合并:将两个集合合并时将元素少的集合合并到元素多的集合上,可以不用定义一个数组来表示个数,直接用T[x].parent  来表示,开始将其初始化为 -1 ,这样如果T[x].parent 为负数代表是根节点,-T[x].parent 就表示所在集合元素个数。

   
  1. void union_find(int x,int y)
  2. {
  3. int ax=find(x) ;
  4. int ay=find(y) ;// 寻找根节点
  5. if(ax!=ay)
  6. {
  7. if(T[ax].parent<T[ay].parent)// 比较节点多少
  8. {
  9. T[ax].parent+=T[ay].parent ;
  10. T[ay].parent=ax ;
  11. }
  12. else
  13. {
  14. T[ay].parent+=T[ax].parent ;
  15. T[ax].parent=ay ;
  16. }
  17. }
  18. }

 

 

文章来源: blog.csdn.net,作者:Linux猿,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/nyist_zxp/article/details/22570277

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。