描述:

并查集是一种描述解决等价关系。能够方便地描述不相交的多个集合。

支持如下操作    1. 建立包含元素 x 的集合  MakeSet(x)

2. 查找给定元素所在的集合 Find(x), 返回所在集合的代表

3. 将两个不相交的集合合并 Union(s1, s2)

本文参考《数据结构与算法分析,C语言描述》这本书,利用数组,给出了并查集的一个容易实现的版本。

采用了按秩合并 和 路径压缩 的方法加速。

数据结构:

用树表示一个集合,树的跟节点就是这个集合的代表元素。

并采用一维数组来非显示地模拟这个森林:

1. 数组长度是总的集合元素个数;

2. s[i] 表示元素 i 的父亲节点;

3. 如果 s[i] 是 负数,表示 i 就是代表元素; 并且负数的绝对值表示所在树的高度。(按高度压缩)

在这样的定义下,Find(x) 非常容易实现,只要从元素 x, 不断往上找,直到找到根节点返回即可。

// return the disjoint set which x belongs to
SetType Find(ElementType x, DisJointSet s)
{
if(s[x] < 0)
return x;
else
return Find(s[x], s);
}

按高度合并:

注意到,Find(x) 的复杂度是树的高度。

按高度合并就是通过将 矮的树 合并到 高的树作为其孩子,从而避免树过高。

//Assume root1 and root2 are roots
void SetUnion(DisJointSet s, SetType root1, SetType root2)
{
if(s[root1] <= s[root2])//root1 is deeper than root2
{
if(s[root1] == s[root2])
s[root1] --;
s[root2] = root1;
}
else
{
s[root1] = root2;
}
}

路径压缩:

这种方法可以与按高度合并兼容,能够得到较高的效率。

它其实是在 Find(x) 这个函数做文章。

在搜索 x 所在树的 root 节点的过程中,将中途的节点都指向 root.

看了下图,大家就能明白了。

代码非常简单:

// return the disjoint set which x belongs to
SetType Find(ElementType x, DisJointSet s)
{
if(s[x] < 0)
return x;
else
return s[x] = Find(s[x], s);
}

完整的代码如下:

/* dis-joint-set implemented by L.J. in Nov.11, 2013 */
/* union by height */
#include "disjointset.h"
#include <iostream>
using namespace std; const int NumSets = 8;
typedef int DisJointSet[ NumSets + 1];
typedef int SetType;
typedef int ElementType; void Initialize(DisJointSet s)
{
for(int i=NumSets; i>0; --i)
s[i] = 0;
} //Assume root1 and root2 are roots
void SetUnion(DisJointSet s, SetType root1, SetType root2)
{
if(s[root1] <= s[root2])//roo1 is deeper than root2
{
if(s[root1] == s[root2])
s[root1] --;
s[root2] = root1;
}
else
{
s[root1] = root2;
}
} // return the disjoint set which x belongs to
SetType Find(ElementType x, DisJointSet s)
{
if(s[x] < 0)
return x;
else
return Find(s[x], s);
}

数据结构《14》----并查集 Union-Find的更多相关文章

  1. 数据结构之并查集Union-Find Sets

    1.  概述 并查集(Disjoint set或者Union-find set)是一种树型的数据结构,常用于处理一些不相交集合(Disjoint Sets)的合并及查询问题. 2.  基本操作 并查集 ...

  2. 数据结构 之 并查集(Disjoint Set)

    一.并查集的概念:     首先,为了引出并查集,先介绍几个概念:     1.等价关系(Equivalent Relation)     自反性.对称性.传递性.     如果a和b存在等价关系,记 ...

  3. 数据结构09—— 并查集(Union-Find)

    一.关于并查集 并查集(Union-Find)是一种树型的数据结构,常用于处理一些不相交集合(Disjoint Sets)的合并及查询问题.并查集(Union-Find)从名字可以看出,主要它涉及两种 ...

  4. 并查集(Union/Find)模板及详解

    概念: 并查集是一种非常精巧而实用的数据结构,它主要用于处理一些不相交集合的合并问题.一些常见的用途有求连通子图.求最小生成树的Kruskal 算法和求最近公共祖先等. 操作: 并查集的基本操作有两个 ...

  5. 【基本数据结构】并查集-C++

    并查集,在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中.这一类问题近几年来反复出 ...

  6. 数据结构(并查集||树链剖分):HEOI 2016 tree

    [注意事项] 为了体现增强版,题目限制和数据范围有所增强: 时间限制:1.5s 内存限制:128MB 对于15% 的数据,1<=N,Q<=1000. 对于35% 的数据,1<=N,Q ...

  7. POJ 1611 The Suspects 并查集 Union Find

    本题也是个标准的并查集题解. 操作完并查集之后,就是要找和0节点在同一个集合的元素有多少. 注意这个操作,须要先找到0的父母节点.然后查找有多少个节点的额父母节点和0的父母节点同样. 这个时候须要对每 ...

  8. 【算法与数据结构】并查集 Disjoint Set

    并查集(Disjoint Set)用来判断已有的数据是否构成环. 在构造图的最小生成树(Minimum Spanning Tree)时,如果采用 Kruskal 算法,每次添加最短路径前,需要先用并查 ...

  9. 【简单数据结构】并查集--洛谷 P1111

    题目背景 AA地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车.政府派人修复这些公路. 题目描述 给出A地区的村庄数NN,和公路数MM,公路是双向的.并告诉你每条公路的连着哪两个村庄,并告诉你 ...

  10. Java 并查集Union Find

    对于一组数据,主要支持两种动作: union isConnected public interface UF { int getSize(); boolean isConnected(int p,in ...

随机推荐

  1. 学习HTML5之塔克大战(详细记录)

    学了一些HTML5的一些基本知识,开始学习制作...... 介绍一些基本知识:  px(像素)--->1px等于多少? 1cm or 2cm -->no  no no! (1).像素是一个 ...

  2. C#类和成员的修饰符

    C#中public.private.protected.internal.protected internal & (2010-09-22 13:33:45)转载 标签: 杂谈 分类: C# ...

  3. Java 线程综述

    线程重在 线程同步和线程通信的编程 1.线程与进程?  线程是指程序在执行过程中,能够执行程序代码的一个执行单元.线程的状态:运行.就绪.挂起(suspend).结束; 进程是指一段正在执行的程序. ...

  4. win7_oracle11g_64位连接32位PLSQL_Developer

      工具/原料 已经装好的64位Oracle数据库 window7_64位的操作系统 PLSQL_Developer 9.0以上版本(目前只有32位的):下面有下载连接! 官方的 instantcli ...

  5. Android 页面滑动

    1.PagerAdapter适配器     PagerAdapter主要是viewpager的适配器,而viewPager是android.support.v4扩展中新添加的一个强大控件,可以实现控件 ...

  6. BZOJ2721 [Violet 5]樱花

    先令n! = a: 1 / x + 1 / y = 1 / a  =>  x = y * a / (y - a) 再令 k = y - a: 于是x = a + a ^ 2 / k  => ...

  7. linux service等命令不能使用的解决办法

    主要是路径没添加进来: 在shell里面输入这条命令:export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin ...

  8. linux bash: sqlplus: command not found 错误处理

    在oracle用户下 ,执行sqlplus命令,抛出如上错误.   解决办法:   1.su oracle   2.cd /home/oracle   3. 执行命令 source .bash_pro ...

  9. Java:标示符 基本数据类型

    标示符: 在程序中自定义的一些名称,例如:变量.类名.方法名…… 组成有数字0~9.大小写英文字母.“$”和下划线“_”组成,且不能由数字开头,以及不能使用java已使用和保留的关键字. Java中的 ...

  10. Ubuntu 13.10 Broadcom BCM4313问题

    开始找不到无线网卡,后来不知道怎么就出来了,但是速度很慢.用下面的方法解决的(我也不知道哪条命令起的作用,反正现在正常了): sudo apt-get remove --purge bcmwl-ker ...