SlideShare a Scribd company logo
1 of 23
アルゴリズムとデータ構
造
8.「平衡木」
2011 年 4 月 26 日(火)
服部 健太
2011/4/26 アルゴリズムとデータ構造 8 2
概要
 平衡木の概念について説明する
 代表的な平衡木である AVL 木と B 木を紹介
する
2011/4/26 アルゴリズムとデータ構造 8 3
平衡木(バランス木: balanced
tree )
 単純な2分探索木では,場合によって形の悪い木が
できてしまうため,最悪の計算量が O(N) となって
しまう.
 左右の部分木のバランスがとれた木を用いる
 挿入や削除時にバランスが崩れたら,ノードを張り替えて
,調整する.
2011/4/26 アルゴリズムとデータ構造 8 4
AVL 木
 左部分木と右部分木の高さの差が,高々1であるような2分探
索木
 AVL 木の条件:
 全ての内部ノード n について以下を満たす
 n が2つの子を持つ場合:
 n が1つの子を持つ場合:その子は葉である
 例:
 これらが AVL 木の条件を満たすことを確認せよ
1).().( ≤− rightnHeightleftnHeight
2011/4/26 アルゴリズムとデータ構造 8 5
AVL 木のノード数と高さの関係
 ノード数 N ,高さ h とする
 高さ h の木のうち,ノード数が最小のものを考える
 h=5 のノード数最小の AVL 木の例:
 直観的には,最小のノード数 N は,高さ h の指数関数のオー
ダーで増える
 逆に考えると,ノード数 N の AVL 木の高さは高々 O(log N) であ
る
 したがって検索に要する最悪の計算量は O(log N) となる
2011/4/26 アルゴリズムとデータ構造 8 6
AVL 木への挿入
 通常の2分探索木と同様に新しい頂点を木の葉とし
て,適切な位置に挿入する
 その結果,左右の部分木の高さの差が2になれば,
木を再構成して, AVL 木の条件を満たすようにす
る
 場合分け:
 ケース1:高さが等しかった場合
 左右の部分木の高さの差は1なので,再構成する必要なし
 ケース2:低い方の部分木に挿入する場合
 左右の部分木の高さが等しくなるので再構成する必要なし
 ケース3:高い方の部分木に挿入する場合
 高さの差が2になるので再構成する必要あり!
2011/4/26 アルゴリズムとデータ構造 8 7
再構成が必要な状態
 ケース Left-Left  ケース Left-Right
A
B
A
B
0
1
2
h
h+1
h+2
h
h-1 h-1
h-1
h
h-1
βα
γ
βα
γ
右部分木が高いケースはこれと左右対称になる
2011/4/26 アルゴリズムとデータ構造 8 8
問題
 以下のようなケースについては,再構成を考
慮しなくて良いのはなぜか説明せよ
A
B
0
1
2
h
h+1
h+2
h h
h-1
βα
γ
2011/4/26 アルゴリズムとデータ構造 8 9
1重回転
 ケース Left-Left の場合
A
BA
B
0
1
2
h
h+1
h+2
h
h-1 h-1 h-1
βα
γ
γ
h-1
β
h
α
右回転
2011/4/26 アルゴリズムとデータ構造 8 10
2重回転
 ケース Left-Right の場合
0
1
2
h
h+1
h+2
左回転
A
B
h-1
h-1 or h-2
h-1
α
γ
3
C
β1 β2
A
α
γ
C
β1
β2
B
右回転
α
B
β1 β2
C
A
γ
2011/4/26 アルゴリズムとデータ構造 8 11
挿入操作の実現
 挿入操作:
 入力:(部分)木のルート( n ),キー( key ),データ( data )
 出力:更新された(部分)木のルート,木の高さが増えたかどうか
def insert(n, key, data):
if n == None:
m = avlnode()
m.key = key; m.data = data; m.left = m.right = None
m.balance = ‘BALANCED’
return m, True
else:
if key < n.key:
n.left, grown = insert(n.left, key, data)
if grown: n, grown = rebalance(n, ‘LEFT’)
elif key > n.key:
n.right, grown = insert(n.right, key, data)
if grown: n, grown = rebalance(n, ‘RIGHT’)
else: error(“key already exists”) # ☆ 2重登録時はエラー
return n, grown
’それぞれ BALANCED’,
‘LEFT’, ‘RIGHT’ とする
木の各ノードに,左右の部
分木の高さが揃っているか
,もしくは左右どちらが高
いかどうかを示すフィール
ドを追加
2011/4/26 アルゴリズムとデータ構造 8 12
挿入操作の実現(2)
 木の再構成処理
 入力:再構成する部分木のルート( n ),挿入した方向( dir )
 出力:再構成された結果更新された部分木のルート,木の高さが増えたかどうか
def rebalance(n, dir):
opp = opposite(dir)
if n.balance == ‘BALANCED’: n.balance = dir; return n, True
elif n.balance == opp: n.balance = ‘BALANCED’; return n, False
n1 = get_child(n, dir)
if n1.balance == dir:
rotate(n, opp)
n.balance = n1.balance = ‘BALANCED’;
return n1, False
elif n1.balance == opp:
n2 = get_child(n1, opp)
rotate(n1, dir); set_child(n, dir, n2); rotate(n, opp)
if n2.balance != dir: n.balance = ‘BALANCED’
else: n.balance = opp
if n2.balance != opp: n1.balance = ‘BALANCED’
else: n1.balance = dir
n2.balance = BALANCED
return n2, False
else: assert False # ありえないケース
2011/4/26 アルゴリズムとデータ構造 8 13
挿入操作の実現(3)
 逆方向
def opposite(dir):
if dir == ‘LEFT’: return ‘RIGHT’
elif: dir == ‘RIGHT’: return ‘LEFT’
 子ノードの取得
def get_child(n, dir):
if dir == ‘LEFT’: return n.left
elif dir == ‘RIGHT’: return n.right
 子ノードのセット
Set_child(n, dir, m):
if dir == ‘LEFT’: n.left = m
elif dir == ‘RIGHT’: n.right = m
 回転
def rotate(n, dir):
opp = opposite(dir)
n1 = get_child(n, opp)
set_child(n, opp, get_child(n1,dir))
set_child(n1, dir, n)
2011/4/26 アルゴリズムとデータ構造 8 14
挿入操作の全体的な動作
 根から木を下に降りて
いき,一番下の段に挿
入
 木をさかのぼりつつ左
右のバランスを回復す
る操作を行う.
 再構成の必要が無く
なったら途中で止まる
 ケース2,もしくは,
ケース3での回転した場
合 挿入
ケース 1
ケース2,または
ケース3(回転)
2011/4/26 アルゴリズムとデータ構造 8 15
AVL 木からの削除
 ノードを削除した結果,左右のバランスが崩
れたら,挿入と同様に木を再構成する
 コードは補足資料参照
A
B
A
B
0
1
2
h
h+1
h+2
h
h-1
h-1
h
h-1
α
γ
βα
γ
h
or
h-1
β
2011/4/26 アルゴリズムとデータ構造 8 16
B 木( B-tree )
 バランスのとれた m 分木
 各ノードに最大 m 個の子供を持つ
 AVL 木と同様に,木を再構成することによってバランスを保つ
 ただし,回転ではなく,ノードを分割したり,併合したりする
 B 木の条件:
 各内部ノードの子供の数の最大は m である
 根以外の各内部ノードの子供の数の最小は
 どの葉も同じ深さである
 B 木の例:
 2/m
2011/4/26 アルゴリズムとデータ構造 8 17
B 木のノードの構造
 各ノードに,隣合う2つの子供の境目を示すキーの
値を入れておく
 キーは,左側のデータの最大値より大きく,右側のデータ
の最小値以下の値を入れることとする
 ノードが k 個の子供を持つ場合,キーの数は k-1 となる
 ここでは,データは葉にだけ入れることにする
6 10 13 20
21 50
30 58 71
3 6 10 14 20 21 39 54 58 77
2011/4/26 アルゴリズムとデータ構造 8 18
B 木の探索
 表の探索
 入力:探索する B 木 (BT) ,キー (key) ,
 出力:見つかったデータ
def search(BT, key):
if BT.root != None:
p = BT.root
while not p.is_leaf:
k = locate(p, key)
p = p.children[k]
if p.key == key: return p.data
retun None
 子を選ぶ手続き
 入力:内部ノード (p) ,キー (key)
 出力:選んだ子のインデックス
def locate(p, key):
i = 0
while i < p.length and key >= p.keys[i]:
i = i + 1
return i
葉か内部ノードか
を区別するフィー
ルド
6 10 13 20
length
ノード内の配列
を線形探索する
2011/4/26 アルゴリズムとデータ構造 8 19
B 木への挿入
 新しいデータの挿入位置を決める
 葉のノードを作り,親のノードの子供として登録する.
 親から見ると,子供が一つ増える
 必要に応じて木の再構成を行う
 子供の数が M-1 以下なら何もしない
 子供の数が M (満杯)ならば,ノードを分割する
 例
α β γ δ ε
INSERT
γ δ εα β
2011/4/26 アルゴリズムとデータ構造 8 20
挿入( B 木)の実現
 挿入操作:
 入力: B 木 (BT) ,キー( key ),データ( data )
def insert(BT, key, data):
if BT.root == None:
leaf = btleaf(); leaf.key = key; leaf.data = data;
BT.root = leaf
return
r = BT.root
if r.is_leaf or r.length == BT.M:
node = btnode(BT.M);
node.length = 1; node.children[0] = r
BT.root = node
if r.length == BT.M: split_child(node, 0, r)
insert_nonfull(node, key, data)
else:
insert_nonfull(r, key, data)
2011/4/26 アルゴリズムとデータ構造 8 21
挿入( B 木)の実現(2)
 分割処理:子ノードを分割して,親ノードに追加する
 入力:親ノード (x), 子ノードの位置 (i) ,子ノード (y)
def split_child(x, i, y):
z = btnode(BT.M)
z.length = BT.M // 2
off = BT.M – z.length
for j in range(0, z.length-1):
z.keys[j] = y.keys[j+off]
z.children[j] = y.children[j+off]
z.children[j+1] = y.children[j+1+off]
y.length = off
for j in range(x.length, i+1, -1):
x.children[j] = x.children[j-1]
x.children[i+1] = z
for j in range(x.length-1, i, -1):
x.keys[j] = x.keys[j-1]
x.keys[i] = y.keys[off-1]; x.length = x.length + 1
6 10 23 30
11 13 15 17 20 22
x
y
i
2011/4/26 アルゴリズムとデータ構造 8 22
挿入( B 木)の実現(3)
 空きがあるノードへの挿入
 入力 : ノード (x) ,キー (key) ,データ (data)
def insert_nonfull(x, key, data):
if x.childlen[0].is_leaf:
leaf = btleaf(); leaf.key = key; leaf.data = data
i = x.length - 1
while i > 0 and key < x.keys[i-1]:
x.children[i+1] = x.children[i]; x.keys[i] = x.keys[i-1]; i = i – 1
if x.children[i].key < key:
x.children[i+1] = x.children[i];x.keys[i] = x.children[i].key
else:
x.keys[i] = key; i = i + 1
x.children[i] = leaf
x.length = x.length + 1
else:
i = locate(x, key)
if x.children[i].length == BT.M:
split_child(x, i, x.children[i])
if key > x.keys[i]: i = i + 1
insert_nonfull(x.children[i], key, data)
2011/4/26 アルゴリズムとデータ構造 8 23
B 木からの削除
 子供が少なくなりすぎた場合
 隣のノードとの間で,子供を再分配する
 隣のノードも子の数が最小限のときは,合併する
γ δ εα β ζ η α β γ δ ε ζ η
γ δ εα β α β γ δ ε

More Related Content

More from Kenta Hattori

オブジェクト指向入門10
オブジェクト指向入門10オブジェクト指向入門10
オブジェクト指向入門10Kenta Hattori
 
オブジェクト指向入門9
オブジェクト指向入門9オブジェクト指向入門9
オブジェクト指向入門9Kenta Hattori
 
オブジェクト指向入門8
オブジェクト指向入門8オブジェクト指向入門8
オブジェクト指向入門8Kenta Hattori
 
オブジェクト指向入門7
オブジェクト指向入門7オブジェクト指向入門7
オブジェクト指向入門7Kenta Hattori
 
オブジェクト指向入門6
オブジェクト指向入門6オブジェクト指向入門6
オブジェクト指向入門6Kenta Hattori
 
オブジェクト指向入門5
オブジェクト指向入門5オブジェクト指向入門5
オブジェクト指向入門5Kenta Hattori
 
オブジェクト指向入門4
オブジェクト指向入門4オブジェクト指向入門4
オブジェクト指向入門4Kenta Hattori
 
オブジェクト指向入門3
オブジェクト指向入門3オブジェクト指向入門3
オブジェクト指向入門3Kenta Hattori
 
ソフトウェア・テスト入門2
ソフトウェア・テスト入門2ソフトウェア・テスト入門2
ソフトウェア・テスト入門2Kenta Hattori
 
ソフトウェア・テスト入門1
ソフトウェア・テスト入門1ソフトウェア・テスト入門1
ソフトウェア・テスト入門1Kenta Hattori
 
ソフトウェア・テスト入門8
ソフトウェア・テスト入門8ソフトウェア・テスト入門8
ソフトウェア・テスト入門8Kenta Hattori
 
ソフトウェア・テスト入門7
ソフトウェア・テスト入門7ソフトウェア・テスト入門7
ソフトウェア・テスト入門7Kenta Hattori
 
ソフトウェア・テスト入門6
ソフトウェア・テスト入門6ソフトウェア・テスト入門6
ソフトウェア・テスト入門6Kenta Hattori
 
ソフトウェア・テスト入門5
ソフトウェア・テスト入門5ソフトウェア・テスト入門5
ソフトウェア・テスト入門5Kenta Hattori
 
ソフトウェア・テスト入門4
ソフトウェア・テスト入門4ソフトウェア・テスト入門4
ソフトウェア・テスト入門4Kenta Hattori
 
ソフトウェア・テスト入門3
ソフトウェア・テスト入門3ソフトウェア・テスト入門3
ソフトウェア・テスト入門3Kenta Hattori
 
アルゴリズムとデータ構造15
アルゴリズムとデータ構造15アルゴリズムとデータ構造15
アルゴリズムとデータ構造15Kenta Hattori
 
アルゴリズムとデータ構造14
アルゴリズムとデータ構造14アルゴリズムとデータ構造14
アルゴリズムとデータ構造14Kenta Hattori
 
アルゴリズムとデータ構造13
アルゴリズムとデータ構造13アルゴリズムとデータ構造13
アルゴリズムとデータ構造13Kenta Hattori
 
アルゴリズムとデータ構造12
アルゴリズムとデータ構造12アルゴリズムとデータ構造12
アルゴリズムとデータ構造12Kenta Hattori
 

More from Kenta Hattori (20)

オブジェクト指向入門10
オブジェクト指向入門10オブジェクト指向入門10
オブジェクト指向入門10
 
オブジェクト指向入門9
オブジェクト指向入門9オブジェクト指向入門9
オブジェクト指向入門9
 
オブジェクト指向入門8
オブジェクト指向入門8オブジェクト指向入門8
オブジェクト指向入門8
 
オブジェクト指向入門7
オブジェクト指向入門7オブジェクト指向入門7
オブジェクト指向入門7
 
オブジェクト指向入門6
オブジェクト指向入門6オブジェクト指向入門6
オブジェクト指向入門6
 
オブジェクト指向入門5
オブジェクト指向入門5オブジェクト指向入門5
オブジェクト指向入門5
 
オブジェクト指向入門4
オブジェクト指向入門4オブジェクト指向入門4
オブジェクト指向入門4
 
オブジェクト指向入門3
オブジェクト指向入門3オブジェクト指向入門3
オブジェクト指向入門3
 
ソフトウェア・テスト入門2
ソフトウェア・テスト入門2ソフトウェア・テスト入門2
ソフトウェア・テスト入門2
 
ソフトウェア・テスト入門1
ソフトウェア・テスト入門1ソフトウェア・テスト入門1
ソフトウェア・テスト入門1
 
ソフトウェア・テスト入門8
ソフトウェア・テスト入門8ソフトウェア・テスト入門8
ソフトウェア・テスト入門8
 
ソフトウェア・テスト入門7
ソフトウェア・テスト入門7ソフトウェア・テスト入門7
ソフトウェア・テスト入門7
 
ソフトウェア・テスト入門6
ソフトウェア・テスト入門6ソフトウェア・テスト入門6
ソフトウェア・テスト入門6
 
ソフトウェア・テスト入門5
ソフトウェア・テスト入門5ソフトウェア・テスト入門5
ソフトウェア・テスト入門5
 
ソフトウェア・テスト入門4
ソフトウェア・テスト入門4ソフトウェア・テスト入門4
ソフトウェア・テスト入門4
 
ソフトウェア・テスト入門3
ソフトウェア・テスト入門3ソフトウェア・テスト入門3
ソフトウェア・テスト入門3
 
アルゴリズムとデータ構造15
アルゴリズムとデータ構造15アルゴリズムとデータ構造15
アルゴリズムとデータ構造15
 
アルゴリズムとデータ構造14
アルゴリズムとデータ構造14アルゴリズムとデータ構造14
アルゴリズムとデータ構造14
 
アルゴリズムとデータ構造13
アルゴリズムとデータ構造13アルゴリズムとデータ構造13
アルゴリズムとデータ構造13
 
アルゴリズムとデータ構造12
アルゴリズムとデータ構造12アルゴリズムとデータ構造12
アルゴリズムとデータ構造12
 

Recently uploaded

My Inspire High Award 2024「他者と自分、対立を防ぐには?」
My Inspire High Award 2024「他者と自分、対立を防ぐには?」My Inspire High Award 2024「他者と自分、対立を防ぐには?」
My Inspire High Award 2024「他者と自分、対立を防ぐには?」inspirehighstaff03
 
My Inspire High Award 2024    「孤独は敵なのか?」
My Inspire High Award 2024    「孤独は敵なのか?」My Inspire High Award 2024    「孤独は敵なのか?」
My Inspire High Award 2024    「孤独は敵なのか?」inspirehighstaff03
 
My Inspire High Award2024「外国人が日本のテーブルマナーに驚く理由は?」
My Inspire High Award2024「外国人が日本のテーブルマナーに驚く理由は?」My Inspire High Award2024「外国人が日本のテーブルマナーに驚く理由は?」
My Inspire High Award2024「外国人が日本のテーブルマナーに驚く理由は?」inspirehighstaff03
 
My Inspire High Award 2024      「家族とは何か」
My Inspire High Award 2024      「家族とは何か」My Inspire High Award 2024      「家族とは何か」
My Inspire High Award 2024      「家族とは何か」inspirehighstaff03
 
My Inspire High Award 2024「なぜ議会への関心が低いのか?」
My Inspire High Award 2024「なぜ議会への関心が低いのか?」My Inspire High Award 2024「なぜ議会への関心が低いのか?」
My Inspire High Award 2024「なぜ議会への関心が低いのか?」inspirehighstaff03
 
My Inspire High Award 2024「Yakushima Islandってなんか変じゃない?」.pdf
My Inspire High Award 2024「Yakushima Islandってなんか変じゃない?」.pdfMy Inspire High Award 2024「Yakushima Islandってなんか変じゃない?」.pdf
My Inspire High Award 2024「Yakushima Islandってなんか変じゃない?」.pdfinspirehighstaff03
 
My Inspire High Award 2024  「正義って存在するの?」
My Inspire High Award 2024  「正義って存在するの?」My Inspire High Award 2024  「正義って存在するの?」
My Inspire High Award 2024  「正義って存在するの?」inspirehighstaff03
 
リアル戦国探究in米沢 当日講座3スライド(スタッフ共有用)『糧は三度はさいせず』についてのスライド
リアル戦国探究in米沢 当日講座3スライド(スタッフ共有用)『糧は三度はさいせず』についてのスライドリアル戦国探究in米沢 当日講座3スライド(スタッフ共有用)『糧は三度はさいせず』についてのスライド
リアル戦国探究in米沢 当日講座3スライド(スタッフ共有用)『糧は三度はさいせず』についてのスライドKen Fukui
 
【ゲーム理論入門】ChatGPTが作成した ゲーム理論の問題を解く #3 Slide
【ゲーム理論入門】ChatGPTが作成した ゲーム理論の問題を解く #3 Slide【ゲーム理論入門】ChatGPTが作成した ゲーム理論の問題を解く #3 Slide
【ゲーム理論入門】ChatGPTが作成した ゲーム理論の問題を解く #3 Slidessusere0a682
 
My Inspire High Award 2024 「AIと仲良くなるには?」
My Inspire High Award 2024 「AIと仲良くなるには?」My Inspire High Award 2024 「AIと仲良くなるには?」
My Inspire High Award 2024 「AIと仲良くなるには?」inspirehighstaff03
 
My Inspire High Award 2024「スーパーマーケットで回収されたキャベツ外葉は廃棄されているの?」
My Inspire High Award 2024「スーパーマーケットで回収されたキャベツ外葉は廃棄されているの?」My Inspire High Award 2024「スーパーマーケットで回収されたキャベツ外葉は廃棄されているの?」
My Inspire High Award 2024「スーパーマーケットで回収されたキャベツ外葉は廃棄されているの?」inspirehighstaff03
 
My Inspire High Award 2024「老いることは不幸なこと?」
My Inspire High Award 2024「老いることは不幸なこと?」My Inspire High Award 2024「老いることは不幸なこと?」
My Inspire High Award 2024「老いることは不幸なこと?」inspirehighstaff03
 
リアル戦国探究in米沢 当日講座2スライド(スタッフ共有用)『人を致すも人に致されず』についてのスライド
リアル戦国探究in米沢 当日講座2スライド(スタッフ共有用)『人を致すも人に致されず』についてのスライドリアル戦国探究in米沢 当日講座2スライド(スタッフ共有用)『人を致すも人に致されず』についてのスライド
リアル戦国探究in米沢 当日講座2スライド(スタッフ共有用)『人を致すも人に致されず』についてのスライドKen Fukui
 
リアル戦国探究in米沢 当日講座1(スタッフ共有用)『兵は詐をもって立つ』についてのスライド
リアル戦国探究in米沢 当日講座1(スタッフ共有用)『兵は詐をもって立つ』についてのスライドリアル戦国探究in米沢 当日講座1(スタッフ共有用)『兵は詐をもって立つ』についてのスライド
リアル戦国探究in米沢 当日講座1(スタッフ共有用)『兵は詐をもって立つ』についてのスライドKen Fukui
 
My Inspire High Award 2024 「本当の『悪者』って何?」
My Inspire High Award 2024 「本当の『悪者』って何?」My Inspire High Award 2024 「本当の『悪者』って何?」
My Inspire High Award 2024 「本当の『悪者』って何?」inspirehighstaff03
 
My Inspire High Award 2024「世の中の流行はどのようにして生まれるのか」
My Inspire High Award 2024「世の中の流行はどのようにして生まれるのか」My Inspire High Award 2024「世の中の流行はどのようにして生まれるのか」
My Inspire High Award 2024「世の中の流行はどのようにして生まれるのか」inspirehighstaff03
 
My Inspire High Award 2024「なぜ、好きなことにいつかは飽きるの」
My Inspire High Award 2024「なぜ、好きなことにいつかは飽きるの」My Inspire High Award 2024「なぜ、好きなことにいつかは飽きるの」
My Inspire High Award 2024「なぜ、好きなことにいつかは飽きるの」inspirehighstaff03
 
リアル戦国探究in米沢 事前講座2スライド(スタッフ共有用)『両雄の強さの秘密』についてのスライド
リアル戦国探究in米沢 事前講座2スライド(スタッフ共有用)『両雄の強さの秘密』についてのスライドリアル戦国探究in米沢 事前講座2スライド(スタッフ共有用)『両雄の強さの秘密』についてのスライド
リアル戦国探究in米沢 事前講座2スライド(スタッフ共有用)『両雄の強さの秘密』についてのスライドKen Fukui
 
TEAMIN Service overview for customer_20240422.pdf
TEAMIN Service overview for customer_20240422.pdfTEAMIN Service overview for customer_20240422.pdf
TEAMIN Service overview for customer_20240422.pdfyukisuga3
 
リアル戦国探究in米沢 事前講座1スライド(スタッフ共有用)『川中島の謎』についてのスライド
リアル戦国探究in米沢 事前講座1スライド(スタッフ共有用)『川中島の謎』についてのスライドリアル戦国探究in米沢 事前講座1スライド(スタッフ共有用)『川中島の謎』についてのスライド
リアル戦国探究in米沢 事前講座1スライド(スタッフ共有用)『川中島の謎』についてのスライドKen Fukui
 

Recently uploaded (20)

My Inspire High Award 2024「他者と自分、対立を防ぐには?」
My Inspire High Award 2024「他者と自分、対立を防ぐには?」My Inspire High Award 2024「他者と自分、対立を防ぐには?」
My Inspire High Award 2024「他者と自分、対立を防ぐには?」
 
My Inspire High Award 2024    「孤独は敵なのか?」
My Inspire High Award 2024    「孤独は敵なのか?」My Inspire High Award 2024    「孤独は敵なのか?」
My Inspire High Award 2024    「孤独は敵なのか?」
 
My Inspire High Award2024「外国人が日本のテーブルマナーに驚く理由は?」
My Inspire High Award2024「外国人が日本のテーブルマナーに驚く理由は?」My Inspire High Award2024「外国人が日本のテーブルマナーに驚く理由は?」
My Inspire High Award2024「外国人が日本のテーブルマナーに驚く理由は?」
 
My Inspire High Award 2024      「家族とは何か」
My Inspire High Award 2024      「家族とは何か」My Inspire High Award 2024      「家族とは何か」
My Inspire High Award 2024      「家族とは何か」
 
My Inspire High Award 2024「なぜ議会への関心が低いのか?」
My Inspire High Award 2024「なぜ議会への関心が低いのか?」My Inspire High Award 2024「なぜ議会への関心が低いのか?」
My Inspire High Award 2024「なぜ議会への関心が低いのか?」
 
My Inspire High Award 2024「Yakushima Islandってなんか変じゃない?」.pdf
My Inspire High Award 2024「Yakushima Islandってなんか変じゃない?」.pdfMy Inspire High Award 2024「Yakushima Islandってなんか変じゃない?」.pdf
My Inspire High Award 2024「Yakushima Islandってなんか変じゃない?」.pdf
 
My Inspire High Award 2024  「正義って存在するの?」
My Inspire High Award 2024  「正義って存在するの?」My Inspire High Award 2024  「正義って存在するの?」
My Inspire High Award 2024  「正義って存在するの?」
 
リアル戦国探究in米沢 当日講座3スライド(スタッフ共有用)『糧は三度はさいせず』についてのスライド
リアル戦国探究in米沢 当日講座3スライド(スタッフ共有用)『糧は三度はさいせず』についてのスライドリアル戦国探究in米沢 当日講座3スライド(スタッフ共有用)『糧は三度はさいせず』についてのスライド
リアル戦国探究in米沢 当日講座3スライド(スタッフ共有用)『糧は三度はさいせず』についてのスライド
 
【ゲーム理論入門】ChatGPTが作成した ゲーム理論の問題を解く #3 Slide
【ゲーム理論入門】ChatGPTが作成した ゲーム理論の問題を解く #3 Slide【ゲーム理論入門】ChatGPTが作成した ゲーム理論の問題を解く #3 Slide
【ゲーム理論入門】ChatGPTが作成した ゲーム理論の問題を解く #3 Slide
 
My Inspire High Award 2024 「AIと仲良くなるには?」
My Inspire High Award 2024 「AIと仲良くなるには?」My Inspire High Award 2024 「AIと仲良くなるには?」
My Inspire High Award 2024 「AIと仲良くなるには?」
 
My Inspire High Award 2024「スーパーマーケットで回収されたキャベツ外葉は廃棄されているの?」
My Inspire High Award 2024「スーパーマーケットで回収されたキャベツ外葉は廃棄されているの?」My Inspire High Award 2024「スーパーマーケットで回収されたキャベツ外葉は廃棄されているの?」
My Inspire High Award 2024「スーパーマーケットで回収されたキャベツ外葉は廃棄されているの?」
 
My Inspire High Award 2024「老いることは不幸なこと?」
My Inspire High Award 2024「老いることは不幸なこと?」My Inspire High Award 2024「老いることは不幸なこと?」
My Inspire High Award 2024「老いることは不幸なこと?」
 
リアル戦国探究in米沢 当日講座2スライド(スタッフ共有用)『人を致すも人に致されず』についてのスライド
リアル戦国探究in米沢 当日講座2スライド(スタッフ共有用)『人を致すも人に致されず』についてのスライドリアル戦国探究in米沢 当日講座2スライド(スタッフ共有用)『人を致すも人に致されず』についてのスライド
リアル戦国探究in米沢 当日講座2スライド(スタッフ共有用)『人を致すも人に致されず』についてのスライド
 
リアル戦国探究in米沢 当日講座1(スタッフ共有用)『兵は詐をもって立つ』についてのスライド
リアル戦国探究in米沢 当日講座1(スタッフ共有用)『兵は詐をもって立つ』についてのスライドリアル戦国探究in米沢 当日講座1(スタッフ共有用)『兵は詐をもって立つ』についてのスライド
リアル戦国探究in米沢 当日講座1(スタッフ共有用)『兵は詐をもって立つ』についてのスライド
 
My Inspire High Award 2024 「本当の『悪者』って何?」
My Inspire High Award 2024 「本当の『悪者』って何?」My Inspire High Award 2024 「本当の『悪者』って何?」
My Inspire High Award 2024 「本当の『悪者』って何?」
 
My Inspire High Award 2024「世の中の流行はどのようにして生まれるのか」
My Inspire High Award 2024「世の中の流行はどのようにして生まれるのか」My Inspire High Award 2024「世の中の流行はどのようにして生まれるのか」
My Inspire High Award 2024「世の中の流行はどのようにして生まれるのか」
 
My Inspire High Award 2024「なぜ、好きなことにいつかは飽きるの」
My Inspire High Award 2024「なぜ、好きなことにいつかは飽きるの」My Inspire High Award 2024「なぜ、好きなことにいつかは飽きるの」
My Inspire High Award 2024「なぜ、好きなことにいつかは飽きるの」
 
リアル戦国探究in米沢 事前講座2スライド(スタッフ共有用)『両雄の強さの秘密』についてのスライド
リアル戦国探究in米沢 事前講座2スライド(スタッフ共有用)『両雄の強さの秘密』についてのスライドリアル戦国探究in米沢 事前講座2スライド(スタッフ共有用)『両雄の強さの秘密』についてのスライド
リアル戦国探究in米沢 事前講座2スライド(スタッフ共有用)『両雄の強さの秘密』についてのスライド
 
TEAMIN Service overview for customer_20240422.pdf
TEAMIN Service overview for customer_20240422.pdfTEAMIN Service overview for customer_20240422.pdf
TEAMIN Service overview for customer_20240422.pdf
 
リアル戦国探究in米沢 事前講座1スライド(スタッフ共有用)『川中島の謎』についてのスライド
リアル戦国探究in米沢 事前講座1スライド(スタッフ共有用)『川中島の謎』についてのスライドリアル戦国探究in米沢 事前講座1スライド(スタッフ共有用)『川中島の謎』についてのスライド
リアル戦国探究in米沢 事前講座1スライド(スタッフ共有用)『川中島の謎』についてのスライド
 

アルゴリズムとデータ構造8

  • 2. 2011/4/26 アルゴリズムとデータ構造 8 2 概要  平衡木の概念について説明する  代表的な平衡木である AVL 木と B 木を紹介 する
  • 3. 2011/4/26 アルゴリズムとデータ構造 8 3 平衡木(バランス木: balanced tree )  単純な2分探索木では,場合によって形の悪い木が できてしまうため,最悪の計算量が O(N) となって しまう.  左右の部分木のバランスがとれた木を用いる  挿入や削除時にバランスが崩れたら,ノードを張り替えて ,調整する.
  • 4. 2011/4/26 アルゴリズムとデータ構造 8 4 AVL 木  左部分木と右部分木の高さの差が,高々1であるような2分探 索木  AVL 木の条件:  全ての内部ノード n について以下を満たす  n が2つの子を持つ場合:  n が1つの子を持つ場合:その子は葉である  例:  これらが AVL 木の条件を満たすことを確認せよ 1).().( ≤− rightnHeightleftnHeight
  • 5. 2011/4/26 アルゴリズムとデータ構造 8 5 AVL 木のノード数と高さの関係  ノード数 N ,高さ h とする  高さ h の木のうち,ノード数が最小のものを考える  h=5 のノード数最小の AVL 木の例:  直観的には,最小のノード数 N は,高さ h の指数関数のオー ダーで増える  逆に考えると,ノード数 N の AVL 木の高さは高々 O(log N) であ る  したがって検索に要する最悪の計算量は O(log N) となる
  • 6. 2011/4/26 アルゴリズムとデータ構造 8 6 AVL 木への挿入  通常の2分探索木と同様に新しい頂点を木の葉とし て,適切な位置に挿入する  その結果,左右の部分木の高さの差が2になれば, 木を再構成して, AVL 木の条件を満たすようにす る  場合分け:  ケース1:高さが等しかった場合  左右の部分木の高さの差は1なので,再構成する必要なし  ケース2:低い方の部分木に挿入する場合  左右の部分木の高さが等しくなるので再構成する必要なし  ケース3:高い方の部分木に挿入する場合  高さの差が2になるので再構成する必要あり!
  • 7. 2011/4/26 アルゴリズムとデータ構造 8 7 再構成が必要な状態  ケース Left-Left  ケース Left-Right A B A B 0 1 2 h h+1 h+2 h h-1 h-1 h-1 h h-1 βα γ βα γ 右部分木が高いケースはこれと左右対称になる
  • 8. 2011/4/26 アルゴリズムとデータ構造 8 8 問題  以下のようなケースについては,再構成を考 慮しなくて良いのはなぜか説明せよ A B 0 1 2 h h+1 h+2 h h h-1 βα γ
  • 9. 2011/4/26 アルゴリズムとデータ構造 8 9 1重回転  ケース Left-Left の場合 A BA B 0 1 2 h h+1 h+2 h h-1 h-1 h-1 βα γ γ h-1 β h α 右回転
  • 10. 2011/4/26 アルゴリズムとデータ構造 8 10 2重回転  ケース Left-Right の場合 0 1 2 h h+1 h+2 左回転 A B h-1 h-1 or h-2 h-1 α γ 3 C β1 β2 A α γ C β1 β2 B 右回転 α B β1 β2 C A γ
  • 11. 2011/4/26 アルゴリズムとデータ構造 8 11 挿入操作の実現  挿入操作:  入力:(部分)木のルート( n ),キー( key ),データ( data )  出力:更新された(部分)木のルート,木の高さが増えたかどうか def insert(n, key, data): if n == None: m = avlnode() m.key = key; m.data = data; m.left = m.right = None m.balance = ‘BALANCED’ return m, True else: if key < n.key: n.left, grown = insert(n.left, key, data) if grown: n, grown = rebalance(n, ‘LEFT’) elif key > n.key: n.right, grown = insert(n.right, key, data) if grown: n, grown = rebalance(n, ‘RIGHT’) else: error(“key already exists”) # ☆ 2重登録時はエラー return n, grown ’それぞれ BALANCED’, ‘LEFT’, ‘RIGHT’ とする 木の各ノードに,左右の部 分木の高さが揃っているか ,もしくは左右どちらが高 いかどうかを示すフィール ドを追加
  • 12. 2011/4/26 アルゴリズムとデータ構造 8 12 挿入操作の実現(2)  木の再構成処理  入力:再構成する部分木のルート( n ),挿入した方向( dir )  出力:再構成された結果更新された部分木のルート,木の高さが増えたかどうか def rebalance(n, dir): opp = opposite(dir) if n.balance == ‘BALANCED’: n.balance = dir; return n, True elif n.balance == opp: n.balance = ‘BALANCED’; return n, False n1 = get_child(n, dir) if n1.balance == dir: rotate(n, opp) n.balance = n1.balance = ‘BALANCED’; return n1, False elif n1.balance == opp: n2 = get_child(n1, opp) rotate(n1, dir); set_child(n, dir, n2); rotate(n, opp) if n2.balance != dir: n.balance = ‘BALANCED’ else: n.balance = opp if n2.balance != opp: n1.balance = ‘BALANCED’ else: n1.balance = dir n2.balance = BALANCED return n2, False else: assert False # ありえないケース
  • 13. 2011/4/26 アルゴリズムとデータ構造 8 13 挿入操作の実現(3)  逆方向 def opposite(dir): if dir == ‘LEFT’: return ‘RIGHT’ elif: dir == ‘RIGHT’: return ‘LEFT’  子ノードの取得 def get_child(n, dir): if dir == ‘LEFT’: return n.left elif dir == ‘RIGHT’: return n.right  子ノードのセット Set_child(n, dir, m): if dir == ‘LEFT’: n.left = m elif dir == ‘RIGHT’: n.right = m  回転 def rotate(n, dir): opp = opposite(dir) n1 = get_child(n, opp) set_child(n, opp, get_child(n1,dir)) set_child(n1, dir, n)
  • 14. 2011/4/26 アルゴリズムとデータ構造 8 14 挿入操作の全体的な動作  根から木を下に降りて いき,一番下の段に挿 入  木をさかのぼりつつ左 右のバランスを回復す る操作を行う.  再構成の必要が無く なったら途中で止まる  ケース2,もしくは, ケース3での回転した場 合 挿入 ケース 1 ケース2,または ケース3(回転)
  • 15. 2011/4/26 アルゴリズムとデータ構造 8 15 AVL 木からの削除  ノードを削除した結果,左右のバランスが崩 れたら,挿入と同様に木を再構成する  コードは補足資料参照 A B A B 0 1 2 h h+1 h+2 h h-1 h-1 h h-1 α γ βα γ h or h-1 β
  • 16. 2011/4/26 アルゴリズムとデータ構造 8 16 B 木( B-tree )  バランスのとれた m 分木  各ノードに最大 m 個の子供を持つ  AVL 木と同様に,木を再構成することによってバランスを保つ  ただし,回転ではなく,ノードを分割したり,併合したりする  B 木の条件:  各内部ノードの子供の数の最大は m である  根以外の各内部ノードの子供の数の最小は  どの葉も同じ深さである  B 木の例:  2/m
  • 17. 2011/4/26 アルゴリズムとデータ構造 8 17 B 木のノードの構造  各ノードに,隣合う2つの子供の境目を示すキーの 値を入れておく  キーは,左側のデータの最大値より大きく,右側のデータ の最小値以下の値を入れることとする  ノードが k 個の子供を持つ場合,キーの数は k-1 となる  ここでは,データは葉にだけ入れることにする 6 10 13 20 21 50 30 58 71 3 6 10 14 20 21 39 54 58 77
  • 18. 2011/4/26 アルゴリズムとデータ構造 8 18 B 木の探索  表の探索  入力:探索する B 木 (BT) ,キー (key) ,  出力:見つかったデータ def search(BT, key): if BT.root != None: p = BT.root while not p.is_leaf: k = locate(p, key) p = p.children[k] if p.key == key: return p.data retun None  子を選ぶ手続き  入力:内部ノード (p) ,キー (key)  出力:選んだ子のインデックス def locate(p, key): i = 0 while i < p.length and key >= p.keys[i]: i = i + 1 return i 葉か内部ノードか を区別するフィー ルド 6 10 13 20 length ノード内の配列 を線形探索する
  • 19. 2011/4/26 アルゴリズムとデータ構造 8 19 B 木への挿入  新しいデータの挿入位置を決める  葉のノードを作り,親のノードの子供として登録する.  親から見ると,子供が一つ増える  必要に応じて木の再構成を行う  子供の数が M-1 以下なら何もしない  子供の数が M (満杯)ならば,ノードを分割する  例 α β γ δ ε INSERT γ δ εα β
  • 20. 2011/4/26 アルゴリズムとデータ構造 8 20 挿入( B 木)の実現  挿入操作:  入力: B 木 (BT) ,キー( key ),データ( data ) def insert(BT, key, data): if BT.root == None: leaf = btleaf(); leaf.key = key; leaf.data = data; BT.root = leaf return r = BT.root if r.is_leaf or r.length == BT.M: node = btnode(BT.M); node.length = 1; node.children[0] = r BT.root = node if r.length == BT.M: split_child(node, 0, r) insert_nonfull(node, key, data) else: insert_nonfull(r, key, data)
  • 21. 2011/4/26 アルゴリズムとデータ構造 8 21 挿入( B 木)の実現(2)  分割処理:子ノードを分割して,親ノードに追加する  入力:親ノード (x), 子ノードの位置 (i) ,子ノード (y) def split_child(x, i, y): z = btnode(BT.M) z.length = BT.M // 2 off = BT.M – z.length for j in range(0, z.length-1): z.keys[j] = y.keys[j+off] z.children[j] = y.children[j+off] z.children[j+1] = y.children[j+1+off] y.length = off for j in range(x.length, i+1, -1): x.children[j] = x.children[j-1] x.children[i+1] = z for j in range(x.length-1, i, -1): x.keys[j] = x.keys[j-1] x.keys[i] = y.keys[off-1]; x.length = x.length + 1 6 10 23 30 11 13 15 17 20 22 x y i
  • 22. 2011/4/26 アルゴリズムとデータ構造 8 22 挿入( B 木)の実現(3)  空きがあるノードへの挿入  入力 : ノード (x) ,キー (key) ,データ (data) def insert_nonfull(x, key, data): if x.childlen[0].is_leaf: leaf = btleaf(); leaf.key = key; leaf.data = data i = x.length - 1 while i > 0 and key < x.keys[i-1]: x.children[i+1] = x.children[i]; x.keys[i] = x.keys[i-1]; i = i – 1 if x.children[i].key < key: x.children[i+1] = x.children[i];x.keys[i] = x.children[i].key else: x.keys[i] = key; i = i + 1 x.children[i] = leaf x.length = x.length + 1 else: i = locate(x, key) if x.children[i].length == BT.M: split_child(x, i, x.children[i]) if key > x.keys[i]: i = i + 1 insert_nonfull(x.children[i], key, data)
  • 23. 2011/4/26 アルゴリズムとデータ構造 8 23 B 木からの削除  子供が少なくなりすぎた場合  隣のノードとの間で,子供を再分配する  隣のノードも子の数が最小限のときは,合併する γ δ εα β ζ η α β γ δ ε ζ η γ δ εα β α β γ δ ε