并查集
来源:互联网 发布:md5加密填充c语言 编辑:程序博客网 时间:2024/06/09 22:52
目录 [隐藏]
1 什么是并查集?
2 并查集的主要操作
3 主要操作的解释及代码
4 并查集的优化
5 时间复杂度
6 源代码
7 习题
[编辑] 什么是并查集?
并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。常常在使用中以森林来表示。
[编辑] 并查集的主要操作
合并两个不相交集合
判断两个元素是否属于同一集合
[编辑] 主要操作的解释及代码
需要注意的是,一开始我们假设元素都是分别属于一个独立的集合里的。
--------------------------------------------------------------------------------
(1) 合并两个不相交集合操作很简单:先设置一个数组Father[x],表示x的“父亲”的编号。那么,合并两个不相交集合的方法就是,找到其中一个集合最父亲的父亲(也就是最久远的祖先),将另外一个集合的最久远的祖先的父亲指向它。
附图一张(摘自CLRS)——Ronice
a图为两个不相交集合,b图为合并后Father(b):=Father(g)
代码:
Procedure Union(x,y:integer);{其中GetFather是下面将讲到的操作}
var fx,fy : integer;
begin
fx := GetFather(x);
fy := GetFather(y);
If fx<>fy then Father[fx] := fy;{指向最祖先的祖先}
end;
--------------------------------------------------------------------------------
(2) 判断两个元素是否属于同一集合仍然使用上面的数组。则本操作即可转换为寻找两个元素的最久远祖先是否相同。可以采用递归实现。(有待补图,制作中)代码:
Function Same(x,y:integer):boolean;
begin
if GetFather(x)=GetFather(y) then
exit(true) else
exit(false);
end;[编辑] 并查集的优化
(1)路径压缩
刚才我们说过,寻找祖先时采用递归,但是一旦元素一多起来,或退化成一条链,每次GetFather都将会使用O(n)的复杂度,这显然不是我们想要的。
对此,我们必须要进行路径压缩,即我们找到最久远的祖先时“顺便”把它的子孙直接连接到它上面。这就是路径压缩了。使用路径压缩的代码如下,时间复杂度基本可以认为是常数的。
附图摘自CLRS:
Procedure Initialize;
var
i:integer;
begin
for i:=1 to maxv do
Father[i]:=i;
end;
Function GetFather(v:integer):integer;
begin
if Father[v]=v then
exit(v) else
Father[v]:=GetFather(Father[v]);
exit(Father[v]);
end;(2)rank合并
合并时将元素少的集合合并到元素多的集合中。
function judge(x,y:integer):boolean;
var fx,fy : integer;
begin
fx := GetFather(x);
fy := GetFather(y);
If fx=fy then
exit(true) else
judge := false;
if rank[fx]>rank[fy] then
father[fy] := fx else begin
father[fx] := fy;
if rank[fx]=rank[fy] then
inc(rank[fy]);
end;
end;初始化:fillchar(rank,sizeof(rank),0);
[编辑] 时间复杂度
O(n*α(n))
其中α(x),对于x=宇宙中原子数之和,α(x)不大于4
事实上,路经压缩后的并查集的复杂度是一个很小的常数。
[编辑] 源代码
加了所有优化的代码框架:
c
c++
[编辑] 习题
Noi2002 银河英雄传说(个人强烈推荐)
CEOI’99 Parity
Kruskal算法的优化
来自"http://www.nocow.cn/index.php/%E5%B9%B6%E6%9F%A5%E9%9B%86"
- HDU3938 并查集 并查集
- 并查集(集并查)
- HDU1232 并查集<并>
- 并查集
- 数据结构-并查集
- 并查集
- 并查集!
- 并查集
- 并查集
- 并查集
- 并查集
- 并查集总结
- 并查集学习
- 并查集
- 并查集
- 并查集
- 所谓并查集
- 并查集
- HDU ACM 1198
- C3TAT2
- (转)字节序问题--大端法小端法
- hibernate 源码学习 多出来的update语句 之一
- 动态创建数组
- 并查集
- java构造函数之private,protected
- 日全食的雷人解释
- 怎样理解“Thinking in C++”?
- Effective STL (一)
- Kruskal算法
- 认清问题是解决问题的一半!
- Hibernate之get和load的区别
- J2EE 开发界面整合到正式环境