数据结构《14》----并查集 Union-Find
描述:
并查集是一种描述解决等价关系。能够方便地描述不相交的多个集合。
支持如下操作 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的更多相关文章
- 数据结构之并查集Union-Find Sets
1. 概述 并查集(Disjoint set或者Union-find set)是一种树型的数据结构,常用于处理一些不相交集合(Disjoint Sets)的合并及查询问题. 2. 基本操作 并查集 ...
- 数据结构 之 并查集(Disjoint Set)
一.并查集的概念: 首先,为了引出并查集,先介绍几个概念: 1.等价关系(Equivalent Relation) 自反性.对称性.传递性. 如果a和b存在等价关系,记 ...
- 数据结构09—— 并查集(Union-Find)
一.关于并查集 并查集(Union-Find)是一种树型的数据结构,常用于处理一些不相交集合(Disjoint Sets)的合并及查询问题.并查集(Union-Find)从名字可以看出,主要它涉及两种 ...
- 并查集(Union/Find)模板及详解
概念: 并查集是一种非常精巧而实用的数据结构,它主要用于处理一些不相交集合的合并问题.一些常见的用途有求连通子图.求最小生成树的Kruskal 算法和求最近公共祖先等. 操作: 并查集的基本操作有两个 ...
- 【基本数据结构】并查集-C++
并查集,在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中.这一类问题近几年来反复出 ...
- 数据结构(并查集||树链剖分):HEOI 2016 tree
[注意事项] 为了体现增强版,题目限制和数据范围有所增强: 时间限制:1.5s 内存限制:128MB 对于15% 的数据,1<=N,Q<=1000. 对于35% 的数据,1<=N,Q ...
- POJ 1611 The Suspects 并查集 Union Find
本题也是个标准的并查集题解. 操作完并查集之后,就是要找和0节点在同一个集合的元素有多少. 注意这个操作,须要先找到0的父母节点.然后查找有多少个节点的额父母节点和0的父母节点同样. 这个时候须要对每 ...
- 【算法与数据结构】并查集 Disjoint Set
并查集(Disjoint Set)用来判断已有的数据是否构成环. 在构造图的最小生成树(Minimum Spanning Tree)时,如果采用 Kruskal 算法,每次添加最短路径前,需要先用并查 ...
- 【简单数据结构】并查集--洛谷 P1111
题目背景 AA地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车.政府派人修复这些公路. 题目描述 给出A地区的村庄数NN,和公路数MM,公路是双向的.并告诉你每条公路的连着哪两个村庄,并告诉你 ...
- Java 并查集Union Find
对于一组数据,主要支持两种动作: union isConnected public interface UF { int getSize(); boolean isConnected(int p,in ...
随机推荐
- linux服务器挂载第二块磁盘图文解说
文章来源:http://www.cndns.com/help/help_con.aspx?hid=394 Linux磁盘挂载是比较常见的管理操作之一.我司橙云预装的linux系统有2块盘,一块为系统盘 ...
- MyBatis实体类映射文件模板
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC " ...
- web基础之hibernate(一篇)
hibernate的一些基本的认识 1. hibenate是一个框架(framework) 2. hibernate是一个orm框架 3. orm(object r ...
- hdu-------(1698)Just a Hook(线段树区间更新)
Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- Java 集合系列 02 Collection架构
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- C++文件读写练习
编写一个程序,统计data.txt文件的行数,并将所有行前加上行号后写到data1.txt文件中. 算法提示: 行与行之间以回车符分隔,而getline()函数以回车符作为终止符.因此,可以采用get ...
- HDU 5773 The All-purpose Zero 求LIS
求最长上升子序列长度: 单纯的dp时间复杂度是O(n*n)的 dp[i] = max(dp[j]+1); (0=<j<=i-1 && a[i]>a[j]) 用二分可以 ...
- java引用类型
java数据类型图: java的数据类型分基本数据类型(原始数据类型)和引用数据类型:1.基本八大类,图中可以很清楚的看到:这种类型的数据变量在声明之后java就会立刻分配给他内存空间.如:sho ...
- 数组越界保护与消息传递black机制
数组越界保护if(index.row <= [array count]) 发送消息[[NSNotificationCenter defaultCenter] postNotificati ...
- centos下cmake安装
步骤一.安装gcc等必备程序包(已安装则略过此步,用gcc -v检测) yum install -y gcc gcc-c++ make automake 步骤二.安装wget (已安装则略过此步) y ...