并查集——(一)概述

并查集概念

在计算机科学中,并查集是一种树型的数据结构,用于处理一些不交集(Disjoint Sets)的合并及查询问题。

并查集数据结构表示

常用的并查集实现有两种方法。

使用数组

我们使用数组来表示这样的数据结构。

比如,我们知道这个集合最大元素个数为 10^5 个,也就是 1 ~ 10^5。那么我们可以定义一个数组来记录每个元素的父节点。

const int MAXN=1e5+4;
int parent[MAXN];
memset(parent, -1, sizeof(parent));

如上定义,元素 i 的父节点保存在对应的 parent[i] 中。例如:

parent[i]=-1,表示节点 i 没有父节点。

parent[3]=5,表示节点 3 的父节点为 5。我们拥有的集合如图所示,

parent[1]=7,表示节点 1 的父节点为 7。我们拥有的集合如图所示,

parent[7]=5,表示节点 7 的父节点为 5。我们拥有的集合如图所示,

使用 STL 的 map 来实现

数组的问题是数组下标不能为负数。当我们元素出现负数的时候,使用 map 更加方便。

map<int, int> ds;

这样就可以表示一个并查集。含义和数组定义并查集是一样的。

并查集操作

并查集的操作主要有两个。查集和并集。

查集

主要作用是查询两个集合是否相交。比如,我们有两个集合 {A} 和 {B},集合 {A} 中有元素 x,集合 {B} 中有元素 y。find_root() 用来查询集合 {A} 和集合 {B} 是否相交。

int x_root=find_root(x);
int y_root=find_root(y);
if (x_root==y_root) {
    集合相交
} else {
    集合不相交
}

并集

主要作用是将两个集合是否合并成为一个新的集合。比如,我们将元素 x 的父亲设置为 y,则就将这两个元素变成一个新的集合。

int x_root=find_root(x);
int y_root=find_root(y);
if (x_root!=y_root) {
    parent[x]=y;
}

并查集举例

元素从 1 ~ 8。我们用数组 parent[9] 来表示。

初始状态

图形表示为,这样,我们有 8 个独立的集合。

对应的 parent 数组值为

parent[1]=-1;
parent[2]=-1;
parent[3]=-1;
parent[4]=-1;
parent[5]=-1;
parent[6]=-1;
parent[7]=-1;
parent[8]=-1;

这样表示,每个元素的父节点都是自己,也就是每个元素都是独立的集合。

合并 3 和 4

集合的图像变为

对应的 parent 数组值为

parent[1]=-1;
parent[2]=-1;
parent[3]=4;
parent[4]=-1;
parent[5]=-1;
parent[6]=-1;
parent[7]=-1;
parent[8]=-1;

我们将元素 3 的父节点指向 4,这样 3 和 4 就在同一个集合中。

合并 1 和 2

集合的图像变为

对应的 parent 数组值为

parent[1]=2;
parent[2]=-1;
parent[3]=4;
parent[4]=-1;
parent[5]=-1;
parent[6]=-1;
parent[7]=-1;
parent[8]=-1;

我们将元素 1 的父节点指向 2,这样 1 和 2 就在同一个集合中。

查询 1 和 5 是否在同一个集合

通过查询,我们知道元素 1 的父节点是 2,元素 5 的父节点是 5。这样说明 1 和 5 不在同一集合。

查询 3 和 4 是否在同一个集合

通过查询,我们知道元素 3 的父节点是 4,元素 4 的父节点是 4。这样说明 3 和 4 在同一集合。

合并 1 和 3

集合的图像变为

我们查询元素 1 的父节点,得到 2;查询元素 3 的父节点,得到 4。对应的 parent 数组值为

parent[1]=2;
parent[2]=4;
parent[3]=4;
parent[4]=-1;
parent[5]=-1;
parent[6]=-1;
parent[7]=-1;
parent[8]=-1;

合并 5 和 8

集合的图像变为

对应的 parent 数组值为

parent[1]=2;
parent[2]=4;
parent[3]=4;
parent[4]=-1;
parent[5]=8;
parent[6]=-1;
parent[7]=-1;
parent[8]=-1;

猜你喜欢

转载自blog.csdn.net/justidle/article/details/108844222