數據結構(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  並查集的初始化

經過一段時間的計算,這些子集合合併爲3個更大的子集合S1={0,6,7,8},S2={1,4,9},S3={2,3,5},此時並查集的屬性表示和存儲結構如圖33-2所示。

                                        圖33-2 用樹表示並查集

爲了得到兩個子集合的並,只需將其中一個子集合根節點的雙親指針指向另一個集合的根節點。因此,S1∪S2可以有如圖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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章