并查集实现

举报
兔老大 发表于 2021/04/23 02:16:47 2021/04/23
【摘要】 并查集是什么东西? 它是用来管理元素分组情况的一种数据结构。 他可以高效进行两个操作: 查询a,b是否在同一组合并a和b所在的组 萌新可能不知所云,这个结构到底有什么用? 经分析,并查集效率之高超乎想象,对n个元素的并查集进行一次操作的复杂度低于O(logn)   我们先说并查集是如何实现的: 也是使用树形结构,但不是二叉树。 每个元素就是一个结点,...

并查集是什么东西?

它是用来管理元素分组情况的一种数据结构。

他可以高效进行两个操作:

  1. 查询a,b是否在同一组
  2. 合并a和b所在的组

萌新可能不知所云,这个结构到底有什么用?

经分析,并查集效率之高超乎想象,对n个元素的并查集进行一次操作的复杂度低于O(logn)

 

我们先说并查集是如何实现的:

也是使用树形结构,但不是二叉树。

每个元素就是一个结点,每组都是一个树。

无需关注它的形状,或哪个节点具体在哪个位置。

 

初始化:

我们现在有n个结点,也就是n个元素。

 

合并:

然后我们就可以合并了,合并方法就是把一个根放到另一颗树的下面,也就是整棵树作为人家的一个子树。

 

查询:

查询两个结点是否是同一组,需要知道这两个结点是不是在一棵树上,让他们分别沿着树向根找,如果两个元素最后走到一个根,他们就在一组。

 

当然,树形结构都存在退化的缺点,对于每种结构,我们都有自己的优化方法,下面我们说明如何避免退化。

  1. 记录每一棵树的高度,合并操作时,高度小的变为高度大的子树即可。
  2. 路径压缩:对于一个节点,只要走到了根节点,就不必再在很深的地方,直接改为连着根即可。进一步优化:其实每一个经过的节点都可以直接连根。

这样查询的时候就能很快地知道根是谁了。

 

下面上代码实现:

和很多树结构一样,我们没必要真的模拟出来,数组中即可。


  
  1. int p[MAX_N];//父亲
  2. int rank[MAX_N];//高度
  3. //初始化
  4. void gg(int n)
  5. {
  6. for(int i=0;i<n;i++)
  7. {
  8. p[i]=i;//父是自己代表是根
  9. rank[i]=0;
  10. }
  11. }
  12. //查询根
  13. int find(int x)
  14. {
  15. if(p[x]==x)return x;
  16. return p[x]=find(p[x])//不断把经过的结点连在根
  17. }
  18. //判断是否属于同一组
  19. bool judge(int x,int y)
  20. {
  21. return find(x)==find(y);//查询结果一样就在一组
  22. }
  23. //合并
  24. void unite(int x,int y)
  25. {
  26. if(x==y)return;
  27. if(rank[x]<rank[y])p[x]=y;//深度小,放在大的下面
  28. else
  29. {
  30. p[y]=x;
  31. if(rank[x]=rank[y])rank[x]++;//一样,y放x后,x深度加一
  32. }
  33. }

实现很简单,应用有难度,以后有时间更新题。

 

文章来源: fantianzuo.blog.csdn.net,作者:兔老大RabbitMQ,版权归原作者所有,如需转载,请联系作者。

原文链接:fantianzuo.blog.csdn.net/article/details/82663647

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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