素集合データ構造
(Union-Find木)
Union-Find木
●互いに交わらない集合(素集合)の族を扱うデー
タ構造
●各集合に「代表」と呼ばれる要素を決めておく
●代表が違う⇔集合が違う
●Union-Find木は2つの操作ができる
●集合の要素からその集合の代表を求める(Find)
●2つの集合を合併する(Union)
Find
4
59
10
1
7 11
63
12 2
8
13
代表
Find
4
59
10
1
7 11
63
12 2
8
13
代表
Find
4
59
10
1
7 11
63
12 2
8
13
代表
Find
4
59
10
1
7 11
63
12 2
8
13
代表
Find
4
59
10
1
7 11
63
12 2
8
13
代表
Find
4
59
10
1
7 11
63
12 2
8
13
代表
4の属する集合と8の属する集合は違う!
Union
4
59
10
1
7 11
63
12 2
8
13
代表
Union
4
59
10
1
7 11
63
12 2
8
13
代表
Union
4
59
10
1
7
11
6
3
12
2
8
13
代表
Union-Find木の実装
●それぞれの集合を根付き木で表す
●代表を根にする
1
5 2
6 3
79
10
11
12
134 8
Find
●親を辿って根を見る
1
5 2
6 3
79
10
11
12
134 8
Find
●親を辿って根を見る
1
5 2
6 3
79
10
11
12
134 8
Find
●親を辿って根を見る
1
5 2
6 3
79
10
11
12
134 8
Find
●親を辿って根を見る
1
5 2
6 3
79
10
11
12
134 8
Union
●一方をもう一方の代表の子にする
1
5 2
6 3
79
10
11
12
134 8
Union
●一方をもう一方の代表の子にする
1
5 2
6 3
7
9
10
11
12
134 8
Union-Find木の計算量
●このままだと最悪計算量は
●Find
●Union
●Findに時間がかかりすぎる
●2種類の高速化法がある
…
O(n)
O(1)
高速化その1:rank
●それぞれの木に  と呼ばれる数値をつける
●要素1個の時
●   同士の木を合併したら    になる
●  が違う木同士を合併するときは、  の高
い方に低い方を合併し、  は  の高い方の
  にする
●   の木の高さは高々 k
rank
rank 0
rank k rank k+1
rank rank
rank k
rank rank
rank
高速化その1:rank
1
5 2
6 3
79
10
11
12
134 8
rank 2
rank 2
rank 1
rank 1
高速化その1:rank
1
5 2
6 3
79
10
11
12
134 8
rank 2
rank 2
rank 1
rank 1
高速化その1:rank
1
5 2
6 3
7
9
10
11
12
134 8
rank 2
rank 2
rank 1
高速化その1:rank
●   の木を作るには少なくとも 個の要素が
必要⇒    の木を作るには最低でも  個
の要素が必要(数学的帰納法)
●要素 個のUnion-Find木は高々
●要素 個のUnion-Find木の高さは高々
●最悪計算量は
●Find
●Union
rank k 2k
rank k+1 2k+1
n rank⌊log2(n)⌋
n ⌊log2(n)⌋
O(log(n))
O(1)
高速化その2:経路圧縮
●Findするときに、根を親にしてしまう
●ついでに根にたどり着くまでの先祖の親も根にして
しまう
●重要なのは根の情報だけだからこれで問題ない
高速化その2:経路圧縮
1
5 2
6 3
7
9
10
11
12
13
4 8
高速化その2:経路圧縮
1
5 2
6 3
7
9
10
11
12
13
4 8
高速化その2:経路圧縮
1
5
2
6 3
79
10
11
12
13
4
8
高速化その2:経路圧縮
●最悪計算量(ならし)
●Find
●Union
●高速化その1と組み合わせることもできる
●経路圧縮しても  は再計算しない
●Find
●Union
●   はアッカーマン関数の逆関数、実質定数
O(log(n))
O(1)
O(α(n))
O(1)
rank
α(n)

素集合データ構造