10. 樹--並查集
阿新 • • 發佈:2019-01-07
並查集
定義
並查集是一種樹型的資料結構,用於處理一些不相交集合(Disjoint Sets)的合併及查詢問題。常常在使用中以森林來表示。
儲存實現
- 邏輯結構:使用樹結構表示集合,樹的每個結點代表一個集合元素
- 物理結構:採用陣列儲存,使用雙親表示法(孩子指向雙親)
例
有三個整數集合:
*
*
*
邏輯結構
物理結構
下標 | Data | Parent |
---|---|---|
0 | 1 | -1 |
1 | 2 | 0 |
2 | 3 | -1 |
3 | 4 | 0 |
4 | 5 | 2 |
5 | 6 | -1 |
7 | 8 | 2 |
8 | 9 | 5 |
9 | 10 | 5 |
Parent:
- 負數表示根結點
- 非負數表示雙親結點的下標
集合的運算
結構定義
typedef struct {
ElementType Data;
int Parent;
} SetType;
查詢集合
查詢某個元素所在的集合,用根結點下標表示
演算法:
- 從陣列中找到該元素的下標
- 根據該元素的Parent找到樹根結點的下標
// 在陣列S中查詢值為X的元素所屬的集合
int Find(SetType S[], ElementType X) {
int i;
for (i = 0; i < MaxSize && S[i].Data != X; i++); // 將i定位到X所在下標
if (i > MaxSize) // 未找到X,返回-1
return -1;
for (; S[i].Parent >= 0; i = S[i].Parent); //將i定位到x所在集合的根結點下標
return i;
}
集合的並運算
基本實現
演算法:
- 分別找到X1和X2兩個元素所在集合樹的根結點
- 如果它們不同根,則將其中一個根結點的父結點指標設定成另一個根結點的陣列下標
void Union(SetType S[], ElementType X1, ElementType X2) {
int Root1, Root2;
Root1 = Find(X1);
Root2 = Find(X2);
if (Root1 != Root2) // 當X1和X2不屬於同一集合時才需要合併
S[Root2].Parent = Root1;
}
優化
- 在儲存時,使用Parent域進行集合數量的記錄。例如1個元素,Parent為-1;7個元素Parent為-7
- 合併時,採用小的集合合併到相對大的集合中