【算法与数据结构】不相交集合——并查集
2012-08-13 13:18
309 查看
来自coursera的课程:普林斯顿大学的算法。
通俗地讲,在一堆item上进行两种操作,一是合并,即将某两个item所在的集合合并为一个大集合;二是查询,即给定的两个item是否属于同一个集合。
高效快速地支持这种操作的数据结构就是并查集。
先看数学原理:
等价关系与等价类
从数学上看,等价类是一个对象(或成员)的集合,在此集合中的所有对象应满足等价关系。若用符号"≡"表示集合上的等价关系,那么对于该集合中的任意对象x,y, z,下列性质成立:
1、自反性:x ≡ x
2、对称性:若 x ≡ y 则 y ≡ x
3、传递性:若 x ≡ y 且 y ≡ z 则 x ≡ z
因此,等价关系是集合上的一个自反、对称、传递的关系。
常用实现:
常用的实现方法是采用森林结构,即相同集合的item同属于一个树。
使用树节点加权优化后,可以保证树的高度不超过logN(其中N为item数量);再加上路径压缩优化,平均复杂度可以在常数级别。
1) remove x 。 即将x从集合中删除
2) find x。即在集合中不小于x的最小整数,例如集合为{1, 2, 4,5},find 3,结果为4.
分析:
可以用并查集来解决这个问题。用并查集来维护相邻的被删除的集合,例如:{0, 1, 2, 3, 4}中删除掉{1,2},那么并查集数据结构中id[]可能是
id[] = {0, 1, 1, 3, 4}。我们只需要为每个id[i]=i的节点增加一个信息,来保存该子树中最大的值。
以5个整数的集合做个演示:
当执行find x操作时,如果id[x]==-1,即结果为x;否则,另id[id[...id[x]...]]为x的根root,那么root+1即为结果,如果root==N,则无解。
通俗地讲,在一堆item上进行两种操作,一是合并,即将某两个item所在的集合合并为一个大集合;二是查询,即给定的两个item是否属于同一个集合。
高效快速地支持这种操作的数据结构就是并查集。
先看数学原理:
等价关系与等价类
从数学上看,等价类是一个对象(或成员)的集合,在此集合中的所有对象应满足等价关系。若用符号"≡"表示集合上的等价关系,那么对于该集合中的任意对象x,y, z,下列性质成立:
1、自反性:x ≡ x
2、对称性:若 x ≡ y 则 y ≡ x
3、传递性:若 x ≡ y 且 y ≡ z 则 x ≡ z
因此,等价关系是集合上的一个自反、对称、传递的关系。
常用实现:
常用的实现方法是采用森林结构,即相同集合的item同属于一个树。
使用树节点加权优化后,可以保证树的高度不超过logN(其中N为item数量);再加上路径压缩优化,平均复杂度可以在常数级别。
class UinonFind { public: UinonFind(int N) { NUM = N; id = new int ; sz = new int ; for (int i = 0; i < N; i ++) id[i] = i, sz[i] = 1; } int root(int i) { while (i != id[i]) { id[i] = id[id[i]]; //优化1:路径压缩 i = id[i]; } return i; } int connected(int p, int q) { return root(p) == root(q); } int connect(int p, int q) { int i = root(p); int j = root(q); //优化2: 加权树 if (sz[i] < sz[j]) {id[i] = j; sz[j] += sz[i];} else {id[j] = i; sz[i] += sz[j];} } private: int *id; int *sz; int NUM; };
例题:
给定N个整数{0,1,2,...,N-1}的集合,以及一些在该集合上的请求:1) remove x 。 即将x从集合中删除
2) find x。即在集合中不小于x的最小整数,例如集合为{1, 2, 4,5},find 3,结果为4.
分析:
可以用并查集来解决这个问题。用并查集来维护相邻的被删除的集合,例如:{0, 1, 2, 3, 4}中删除掉{1,2},那么并查集数据结构中id[]可能是
id[] = {0, 1, 1, 3, 4}。我们只需要为每个id[i]=i的节点增加一个信息,来保存该子树中最大的值。
以5个整数的集合做个演示:
操作 | id[] | max[] |
初始 | {-1,-1,-1,-1,-1} | {-1,-1,-1,-1,-1} |
remove 1 | {-1,1,-1,-1,-1} | {-1,1,-1,-1,-1} |
remove 4 | {-1, 1, -1, -1, 4} | {-1, 1,-1,-1,4} |
remove 2 | {-1, 1,1,-1,4} | {-1,2,-1,-1,4} |
相关文章推荐
- 用于不相交集合的数据结构(算法导论第21章-并查集)
- 算法起步之并查集(不相交集合数据结构)
- 用于不相交集合的数据结构(并查集)
- [算法系列之二十八]并查集(不相交集合)
- 算法导论之不相交集合森林——并查集
- [算法系列之二十八]并查集(不相交集合)
- [算法导论读书笔记]用于不相交集合的数据结构(并查集)
- 实用算法实现-第12篇 不相交集合(并查集)
- 实用算法实现-第12篇 不相交集合(并查集)
- 并查集(用于不相交集合的数据结构)
- 并查集(不相交集合数据结构)
- 算法导论学习笔记(15)——用于不相交集合的数据结构
- 不相交集合的数据结构-并查集
- 并查集——用于不相交集合的数据结构
- 算法导论 第21章 用于不相交集合的数据结构
- 【数据结构&&算法系列】并查集简单介绍
- 【并查集】 不相交集合 - 并查集 教程(文章作者:Slyar)
- 用于不相交集合的数据结构
- JS中的算法与数据结构——集合(Set)
- 算法导论学习笔记-第二十一章-用于不相交集合的数据结构