不带权并查集的操作
来源:互联网 发布:索隆的三把刀最好淘宝 编辑:程序博客网 时间:2024/06/05 20:57
一、不带权并查集的操作:
1.找祖宗节点(树的根节点)体现在Find函数里。
2.连接两棵树,体现在unite函数里。
3.路径压缩,体现在Find函数里。
4.初始化什么乱七八糟的东西。
1、2、4操作是必要的,3是优化操作。
这里我习惯pre数组记录每个节点的根节点。
二、朴素做法:
1.找祖宗不加路径压缩的代码:
int Find(int x){ while(x!=pre[x]) x=pre[x]; return x;}
这个很朴素,只要这个节点的根不是自己,就一直往自己的父亲节点上找。
2.合并两棵树:
void unite(int x,int y){ pre[x]=y;}
但是这个代码是错误的。其实这一共有两种情况。一种是x和y在同一棵树上,比如1和3在一棵树,同是2和3在一棵树,又给你个条件是1和2在一棵树上,当x和y在用一棵树上式,这个代码还算正确。第二种情况是x和y不在同一颗书上,这个代码就是错误的了,因为除了要完成把x和y联系到一起这个任务之外,我们还要维护树的性质。pre数组记录了这个点的父节点,如果仅仅是pre[x]=y的话会破坏被合并的树父节点和子节点的关系(子节点和父节点的关系就变了)。那么我们要怎么做呢?让他们的根连接根(让x树的根连到y树的根),这样就避免了破坏树的性质了。
代码如下:
void unite(int x,int y){ int fx=Find(x); int fy=Find(y); if(fx!=fy) { pre[fx]=fy; }}
这个代码的意思是,先找到x所在的树的根,再找到y所在的树的根,如果两个根节点不一样(两个点不在同一棵树上),那么就把两棵树的根节点联系在一起,如果两个点本身就在一棵树上,就不做操作(你们本来就在一棵树上,本来就已经联系起来了,那还再次连什么连……)。
到此,Find函数和unite函数就已经能够实际应用了,就是基本操作的朴素版。
三、优化
其实这里的习惯优化只有一个,那就是大招——路径压缩。(其实还有启发式合并)
举个例子:
以1为根的树有两个叶子,标号2,3;以4为根的树有两个叶子,标号为5,6。(最好自己画个图哦)
当我们用上述的unite函数连接3、5这两个点之后,会有这样的树:
4是根节点,有三个子节点分别是1、5、6。1这个子节点还有两个子节点分别是2、3。
这样下次找2的根节点时候,要先找到1这个父节点,才能找到4这个祖宗。
因为并查集强调的不是树的结构而是集合,只要在一棵树上的元素,就是在一个集合里。一般解决pre数组这个森林里有多少棵树这个问题。
那我让2和3节点直接认4这个祖宗做父节点就是了,反正不会对最终的结果造成影响,还能快速的找到点的祖宗。
怎么做呢?
在Find函数里做手脚:
int Find(int x){ if(x==pre[x]) return pre[x]; else pre[x]=Find(pre[x]);}
这里采用了递归的方法。(还有一种写法是循环的,不过个人不习惯用那个)Find函数最终会带着根的序号返回,赋给x所有的先辈的节点,让它们直接认祖宗为父亲,也就压缩了路径。
注意:路径压缩不是在合并的时候压缩的,而是在找根节点的时候压缩的。
- 不带权并查集的操作
- 并查集操作
- 并查集操作
- 并查集的基本操作
- 并查集的基本操作
- 不同类型元素的并查集操作
- 并查集的基本操作模版
- 并查集基本操作
- 【NYOJ 1022】合纵连横 【并查集的 并查删操作】
- hdu4496并查集的删边操作
- nyoj1022合纵连横(带分离操作的并查集)
- UVA11987(带权并查集的删除操作)
- NYOJ-1022合纵连横(并查集的删除操作)
- foj2155 - 盟国 (并查集的删除操作)
- NYOJ1022合纵连横(支持删除操作的并查集)
- uva11987(加权并查集的删除操作)
- UVA 11987 Almost Union-Find (带权并查集的操作及并查集的删除操作)
- 不带权并查集
- 居民身份证号码的编码规则
- HTML常用的特殊符号总结 2014年9月12日 22704次浏览 html中经常会用到一些特殊符号,例如箭头,雪花,心形等等,这些符号就不用css样式或者图片来写了,直接用html特殊符号可以实现。
- Android Studio 3.+版本 Gradle中Complie和Implementation
- CodeM 数码
- 二叉树相关操作(前序遍历,中序遍历,后序遍历,层次序遍历等)递归和非递归实现
- 不带权并查集的操作
- ILRuntime第二课预备知识-ILRuntime中的反射
- Java动态代理(代理模式/委托模式)
- 在Ubuntu上用命令创建你的第一个Qt程序
- [linux] 内核同步机制 -- 原子操作
- ArrayList源码简略解读
- 安装Dubbo管理控制台
- Android开发者e周报 第1期
- 二级联动的下拉框