アルゴリズムとデータ構造
2012 年 6 月 18 日
酒居敬一
([email protected])http://www.info.kochi-tech.ac.jp/k1sakai/Lecture/ALG/2012/index.html
1
平衡木
• 木を作り変えて性能のよい形に保つ
• 作り変えるための計算量が多すぎてもダメ
– ほどほどにバランスをとる
• AVL 木
– 2分探索木の一種
• B 木
– 多分木 (maybe tree ではなく、 multiway tree)
AVL 木
• どの頂点においても、
その左部分木と右部分木の高さの差が
+1, 0, -1 のいずれかである2分探索木
Fibonacchi 数列
h=2
2
1
1
+ +
=
h− h−h
N N
N
とおくと、
+ 1
=
hh
N
f
2 ,
1 )
2
(h ≥ N0 = N1 =
1 )
1 (
1+
2+ +
=
h− h−h
N N
f
頂点数最少の
AVL
木の頂点数) 1 (
) 1
(
1+ +
2+
= N
h−N
h−2
1 −
−
+
= f
nf
n0
= 2 f
1
= 3 f
この漸化式は
Fibonacci
数列として有名17
9 21
23 13
11 5
7 3
19
17
9 21
23 13
11 5
7 3
19
1
1 を挿入すると
…
バランスが崩れて、
AVL
木でなくなった。(
のノードの左部分木と右部分木) 90
ページa)
15
15
17
17
9 21
23 13
11 5
7 3
19
1 9 と を入れ替える(回転する)。 17
17 9
21
23 13
11 5
7 3
19 1
15
15
17
9 21
13 23 11
5
7 3
19
91
ページc)
15
17
9 21
23 13
11 5
7 3
19
10 10 を挿入すると
…
バランスが崩れて、
AVL
木でなくなった。15
17 9
21
23 13
11 5
7 3
19 10
1
回転してもダメ15
17 9
21 13
11
5 15
を根に置くことにして、
2回転します。
13
17
9 21
23 13
11 5
7 3
19
10 10 を挿入すると
…
バランスが崩れて、
AVL
木でなくなった。15
削除の場合
1. 通常の2分探索木として頂点を削除 2. 削除した結果の木が、
AVL 木の条件を満たさない場合
Ø 木の形が90ページ a) では一重回転 Ø 木の形が91ページ c) では二重回転
Ø 教科書98ページにも、そう書いてある。
Ø 挿入にせよ削除にせよ、結果の木の形で
再構成の要・不要を判断する。ということ。
B 木( B-tree )
Ø 二分木ではないが、探索用のm分木 Ø いわゆる平衡木
Ø 順序木である
Ø B 木を構成するためのルール
Ø 根から葉までの深さはどの葉についても同じである Ø 各頂点(葉以外)の子の数は最大 m である
Ø 各頂点(葉以外)の子の数は最小 である
Ø
は切り上げを意味する記号であるØ
根は例外で、最小2
である頂点の構造
頂点にはデータは置かない 探索キーだけをおく
キーは枝をたどるときの境目
B 木の探索
Ø 途中の頂点にはデータは入ってない
Ø 入ってる値は部分枝の選択のためのキー値 Ø データは葉の部分におかれている
Ø
そうしない実装もあるØ 根から部分木を選択しながら下降する
Ø 部分木の選択には O(log m) 必要
Ø 葉に達したら探索は終了
Ø 葉の値と一致すれば成功、そうでなければ失敗
B 木の頂点に置く境界値
• 頂点に置かれる値は部分木選択に使われる
• 境界値の条件は次の2つを満たす
– 左に位置する部分木の最大値以上 – 右に位置する部分木の最小値以下
• 条件を満たす値は複数あるがどれでもいい
境界値の左部分木 境界値の右部分木 境界値
7 31
3 6 22 29 49 - -
0 3 6 7 22 29 31 49
7未満の数 7以上31未満の数 31以上の数
• 未満, less than, より小さい
• 以上, greater than or equal to
29
を探索3 44
を探索 を探索探索失敗
新しいデータ(子)を追加するとき
1. 追加すべき位置(親の頂点)を決定します 2. 親の頂点に空きがあるか調べます
3. 空きがない場合は親の頂点を分割します 親の親の頂点から新たに枝を増やします
親が根である場合は、新たな根を親の親として増やします 4. 子を頂点に追加します
データ(子)を削除するとき
1. 削除すべきデータを探索し、削除します
2. 親からの枝の本数が最少数を満たすかどうか調べます 3. 最少数に満たない場合は隣の頂点と子を按分します
按分した結果最少数を満たせない場合は隣の頂点と併合します 親が根である場合に最少数2を割ったら、根を削除します
計算量の考察
• キー値の比較を 1 回行うと候補は半減する
– 候補が半減する場合がもっとも効率が良い – 半減するようにデータを保持する
•
例:平衡木を使う• ちょうど半分ずつ絞りこめば O(log N)
• キーの比較という手法を使う限りはこれ以
上探索の効率はよくならない。
17 9
21
23 13
11 5
7
3 10 19
8ページ下の図から を削除します。
15