数据结构(33)树的应用--并查集

并查集是一种简单的集合表示,它支持以下3种操作:

1)Union(S,Root1,Root2):把集合S中的子集合Root2并入子集合Root1。要求Root1和Root2互不相交,否则不执行合并。

2)Find(S,x):查找集合S中单元素x所在的子集合,并返回该子集合的名字。

3)Initial(S):将集合S中的每个元素都初始化为只有一个单元素的子集合。

通常用树(森林)的双亲表示法作为并查集的存储结构,每个子集合以一棵树表示。所有表示子集合的树,构成表示全集合的森林,存放在双亲表示数组内。通常用数组元素的下标代表元素名,用根结点的下标代表子集合名,根结点的双亲结点为负数。

例如,若设有一个全集合为S={0,1,2,3,4,5,6,7,8,9},初始化时每个元素自成一个单元素集合,每个子集合的数组值为-1,如图33-1所示。

数据结构(33)树的应用--并查集_第1张图片

                      图33-1  并查集的初始化

经过一段时间的计算,这些子集合合并为3个更大的子集合S1={0,6,7,8},S2={1,4,9},S3={2,3,5},此时并查集的属性表示和存储结构如图33-2所示。

数据结构(33)树的应用--并查集_第2张图片

                                        图33-2 用树表示并查集

为了得到两个子集合的并,只需将其中一个子集合根节点的双亲指针指向另一个集合的根节点。因此,S1∪S2可以有如图33-3所示的表示。

数据结构(33)树的应用--并查集_第3张图片

                                   图33-3  S1∪S2可能的表示方法

在采用树的双亲指针数组表示作为并查集的存储表示时,集合元素的编号从0到size-1。其中size是最大元素的个数。下面是并查集主要运算的实现。

并查集的结构定义:

#define SIZE 100
int UFSets[SIZE];    //集合元素数组(双亲指针数组)

并查集的初始化:

void Inital(int S[])
{
    for(int i = 0; i < SIZE; ++i)
        UFSets[i] = -1;
}

并查集的Find操作(查找并返回包含元素x的树的根)

int Find(int UFSets[],int x)
{
    while(UFSets[x] > 0)
        x = S[x];
    return x;    
}

并查集的Union操作(两个不相交的子集合的并集)

void Union(int S[],int Root1,int Root2)
{
    S[Root2] = Root1;
}

 

你可能感兴趣的:(数据结构)