并查集 入门 以及状态压缩 C
2016-07-27 20:07
330 查看
并查集(Union-find Sets)是一种非常精巧而实用的数据结构,它主要用于处理一些不相交集合的合并问题。一些常见的用途有求连通子图、求最小生成树的
Kruskal 算法和求最近公共祖先(Least Common Ancestors, LCA)等。
使用并查集时,首先会存在一组不相交的动态集合 S={S1,S2,⋯,Sk}S={S1,S2,⋯,Sk},一般都会使用一个整数表示集合中的一个元素。、
顾名思义 并查集有两个操作:
1:合并两个集合
2:查找某元素属于哪个集合
并查集的实现原理也比较简单,就是使用树来表示集合,树的每个节点就表示集合中的一个元素,树根对应的元素就是该集合的代表 如图
并查集的表示 初始化并查集
有{a,b,d,c}和{e,f,g}两个集合其中a,和e分别为l两棵数的根也是各个集合的代表,对于并查集这种数据结构查找一个元素是否在集合里面相对是比较快的它仅仅只需要不断寻找其父节点一直到根节点复杂度为O(N)并且其实现方法也相对容易,只需用一个一维数组来保存其父指针(开始起指针指向他自己即A
=N)同样合并两个集合只需要将其中一个集合的根指针指向另一集合的根即可
查找代码:
但是当一个集合形成的树深度太深在递归的时候便失去啦它的意思还用可能当树退化成一根链事其处理和数组就差不多啦,对于这种问题通常有两种解决方法
1:将深度小的集合合并在深度大的集合上去;
2:路径压缩;
路径压缩:路径压缩,就是在每次查找时,令查找路径上的每个节点都直接指向根节点如图
同样路径压缩有两个方法分别为递归版和非递归版
递归版:
非递归版:
出处:http://www.cnblogs.com/cyjb/
GitHub:https://github.com/CYJB/
Kruskal 算法和求最近公共祖先(Least Common Ancestors, LCA)等。
使用并查集时,首先会存在一组不相交的动态集合 S={S1,S2,⋯,Sk}S={S1,S2,⋯,Sk},一般都会使用一个整数表示集合中的一个元素。、
顾名思义 并查集有两个操作:
1:合并两个集合
2:查找某元素属于哪个集合
并查集的实现原理也比较简单,就是使用树来表示集合,树的每个节点就表示集合中的一个元素,树根对应的元素就是该集合的代表 如图
并查集的表示 初始化并查集
有{a,b,d,c}和{e,f,g}两个集合其中a,和e分别为l两棵数的根也是各个集合的代表,对于并查集这种数据结构查找一个元素是否在集合里面相对是比较快的它仅仅只需要不断寻找其父节点一直到根节点复杂度为O(N)并且其实现方法也相对容易,只需用一个一维数组来保存其父指针(开始起指针指向他自己即A
=N)同样合并两个集合只需要将其中一个集合的根指针指向另一集合的根即可
查找代码:
find2(x) { r = x; while (set[r] != r) r = set[r]; return r; }合并代码:
merge2(a, b) { if (a<b) set[b] = a; else set[a] = b; }
但是当一个集合形成的树深度太深在递归的时候便失去啦它的意思还用可能当树退化成一根链事其处理和数组就差不多啦,对于这种问题通常有两种解决方法
1:将深度小的集合合并在深度大的集合上去;
2:路径压缩;
路径压缩:路径压缩,就是在每次查找时,令查找路径上的每个节点都直接指向根节点如图
同样路径压缩有两个方法分别为递归版和非递归版
递归版:
int find(int x) //查找x元素所在的集合,回溯时压缩路径 { if (x != parent[x]) { parent[x] = find(parent[x]); //回溯时的压缩路径 } //从x结点搜索到祖先结点所经过的结点都指向该祖先结点 return parent[x]; }
非递归版:
int find(int x) { int k, j, r; r = x; while(r != parent[r]) //查找跟节点 r = parent[r]; //找到跟节点,用r记录下 k = x; while(k != r) //非递归路径压缩操作 { j = parent[k]; //用j暂存parent[k]的父节点 parent[k] = r; //parent[x]指向跟节点 k = j; //k移到父节点 } return r; //返回根节点的值 }图片等资料来自于:作者:CYJB
出处:http://www.cnblogs.com/cyjb/
GitHub:https://github.com/CYJB/
相关文章推荐
- linux 入门常用命令(2)
- nyoj722 数独
- Mysql date的大于某一个时间点
- getLayoutParams()和setLayoutParams()方法源码,有需要的朋友可以参考下。
- 7/27个人赛——感想
- Sphinx的安装和yii框架的使用
- LintCode之167 链表求和
- 安卓在两个控件中间画一条竖线
- BFC
- 做好这些面试准备,你还担心什么?
- 【Mysql】存储emoji表情报错(Incorrect string value: '\xF0\x9F\x98\x82\xF0\x9F...')的解决方案
- ★ AutoCAD 2015 必备优化★ (使用软件自带的"将设置重置为默认值"功能,会还原以下所有优化为软件默认值)
- SQLiteOpenHelper类的onCreate方法什么时候被执行--只有database.db不存在的时候
- HTML5 Web API:postMessage
- HDU 4588 Count The Carries(规律)
- POJ 3087
- Mini2440烧写Linux系统
- hashmap两种遍历总结!
- spark配置IntelliJ开发环境详解
- [HihoCoder]#1289 : 403 Forbidden