情報システム基盤学 基礎 1 アルゴリズムとデータ構造
DESCRIPTION
情報システム基盤学 基礎 1 アルゴリズムとデータ構造. Elements of Information Systems Fundamentals1. アルゴリズムとデータ構造 第 3 回 木 (Tree) と 2 分探索木 (Binary search tree). 目次 : 今日やること. 木構造 木の深さ優先探索,幅優先探索 2 分木・ 2 分探索木 2 分探索 頂点の挿入 頂点の削除 木の頂点の番号づけ. 木構造. 木構造 :上から下へ枝分かれした構造. r. :頂点(点). :辺. a. b. c. d. :根. e. f. h. - PowerPoint PPT PresentationTRANSCRIPT
情報システム基盤学 基礎1
アルゴリズムとデータ構造
Elements of Information Systems Fundamentals1
1
アルゴリズムとデータ構造 第3 回
木 (Tree) と2 分探索木 (Binary search tree)
目次 : 今日やること
木構造 木の深さ優先探索,幅優先探索 2 分木・ 2 分探索木
2 分探索 頂点の挿入 頂点の削除
木の頂点の番号づけ
4
木構造
5
木(根つき木)の例
木構造:上から下へ枝分かれした構造
:頂点(点):辺
:根
r
a
e
n
mlk
jihgf
dcb
深さ
親と子
祖先と子孫頂点 x を根とする部分木
葉と内点
木構造
6
木(根つき木)の例
木構造:上から下へ枝分かれした構造
:頂点(点):辺
:根
r
a
e
n
mlk
jihgf
dcb
親と子
隣接する 2 頂点のうち , ・根に近い方 → 親 ・根から遠い方 → 子
木構造
7
木(根つき木)の例
木構造:上から下へ枝分かれした構造
:頂点(点):辺
:根
r
a
e
n
mlk
jihgf
dcb
葉と内点
子をもたない頂点葉:
葉以外の頂点内点:
木構造
8木(根つき木)の例
木構造:上から下へ枝分かれした構造
:頂点(点):辺
:根
r
a
e
n
mlk
jihgf
dcb
子孫と祖先
頂点 x の祖先:頂点 x から根へのパス上
に存在する点( x は含まない)頂点 x の子
孫:頂点 x を祖先として含む頂点
木構造
9木(根つき木)の例
木構造:上から下へ枝分かれした構造
:頂点(点):辺
:根
r
a
e
n
mlk
jihgf
dcb
頂点 x を根とする部分木頂点 x を根とする部分
木:頂点 x と x の子孫からなる木
x
深さ0深さ1
深さ2
深さ3
深さ4
木構造
10高さ“ 5” の木の例
木構造:上から下へ枝分かれした構造 :頂点
(点):辺
:根
r
a
e
n
mlk
jihgf
dcb
深さ頂点 x の深さ:頂点 x から根へのパ
ス上にある辺の数
x
まとめ : 木構造について見てきた
11
木(根つき木)の例
木構造:上から下へ枝分かれした構造
:頂点(点):辺
:根
r
a
e
n
mlk
jihgf
dcb
深さ
親と子
祖先と子孫頂点 x を根とする部分木
葉
12
12
5 18
2 9 15 19
17例: 12, 5, 2, 9, 18, 15, 17, 19
A
B C
Search(A) 1.Mark A; 2.if ( A is leaf )
return;3.Search(B); 4.Search(C);5.Search(D);
深さ優先探索(depth-first search)
木の深さ優先探索
現ノードAの最左の子ノードから順に再帰降下する探索
D
13
12
5 18
2 9 15 19
17
例: 12, 5, 18, 2, 9, 15, 19, 17
A
B C
木の幅優先探索現ノードAの子ノードを全て検査してから次の深さの子ノードを順に検査する探索
D
A
B C
木の幅優先探索現ノードAの子ノードを全て検査してから次の深さの子ノードを順に検査する探索
D
BFS(A) 1. enq(Q, A); 1.While (Q != Φ) do2. q = deq(Q);3. mark q;4. enq all children of q;5.end
E F G H
A, B, C, D, E, F, G, H
目次 : 今日やること
木構造 2 分木・ 2 分探索木
2 分探索 頂点の挿入 頂点の削除
木の頂点の番号づけ トライ・サフィックス木(の紹介だけ)
19
2 分木
20
2 分木の定義
子の数が高々 2 個の木(ちょっと特殊な
木)
2 分木
木
2 分木
21
2 分木の例その 1
2 分木の例その 2 :完全 2 分木
(内点は 2 個の子をもつ)
2 分木の例その 3 :これも 2
分木
2 分木の定義
子の数が高々 2 個の木(ちょっと特殊な
木)
1 = 20
完全 2 分木の頂点数について
22
2 = 21
4 = 22
8 = 23
完全 2 分木の頂点数
高さ d の完全 2 分木 は 2d – 1 個の頂点をもつ
各点は , ちょうど 2 個の子をもつので
1 つ深くなるごとに頂点数は 2 倍
2 倍
2 倍
2 倍
高さ d の完全 2 分木 の頂点の個数を n とすると
n = ∑ 2i
i = 0
d-1
= 2d – 1
高さ = “ 最大深さ + 1” と考えてください(左下の木の高さは“ 4” )
注意:
目次 : 今日やること
木構造 2 分木・ 2 分探索木
2 分探索 頂点の挿入 頂点の削除
木の頂点の番号づけ トライ・サフィックス木(の紹介だけ)
23
2 分探索木
24
2 分探索木とは…
2 分木の構造をデータ構造として利用したもの各点にキー( = 自然数)を 1
つ格納左の子を根とする部分木に , より小さなキーを格納右の子を根とする部分木に , より大きなキーを格納
2 分探索木の例:
18
10 35
5 13 23 46
3 7 20 50
小 大
2 分探索木のイメージ:
x
x より小x より大
18
10
35 23
35
2 分探索木の実装
25
2 分探索木の表し方の例
頂点を構造体で表す struct vertex { int key; struct vertex *p; struct vertex *left; struct vertex *right;};
フィールドの構成: ・ キー フィールド ・ 親フィールド ・ 左の子 フィールド ・ 右の子 フィールド18
10 35
5 13 23 46
3 7 20 50
こんな感じ
“ キー = 自然数”と考えてね !!
35
46
502073
13
目次 : 今日やること
木構造 2 分木・ 2 分探索木
2 分探索 頂点の挿入 頂点の削除
木の頂点の番号づけ トライ・サフィックス木(の紹介だけ)
26
2 分探索( = 2 分探索木上での探索)
27
問題
キー k が与えられたとき , 2 分探索木上で k を探したい
アルゴリズム
キー 7 の探索:水色網かけキー 28 の探索:ピンク網かけ
18
10 35
5 13 23 46
3 7 20 50
(根からスタートして)現在の頂点のキーと k を比較
両者は等しい → 現在の頂点を返し , 終了キー k の方が大きい → 右の子へ移動キー k の方が小さい → 左の子へ移動(子がなければ NULL を返す)
繰り返し
2 分探索 : 擬似コード
28
TREE-SEARCH(x,k)
1 if x = NULL or k = key[x]
2 then return x
3 if k < key[x]
4 then return TREE-SEARCH(left[x],k)
5 else return TREE-SEARCH(right[x],k)
x: 2 分探索木上の頂点key[x]: 頂点 x がもつキーleft[x]: 頂点 x の左の子right[x]: 頂点 x の右の子
x key[x]
key[x]より小
key[x]より大
目次 : 今日やること
木構造 2 分木・ 2 分探索木
2 分探索 頂点の挿入 頂点の削除
木の頂点の番号づけ トライ・サフィックス木(の紹介だけ)
29
2 分探索木へデータを挿入
30
2 分探索木へのデータ挿入
2 分探索木へ点を 1 つ追加する(※ 2 分探索木の性質が失われないように!)
12
5 18
2 9 15 19
17 13
12
5 18
2 9 15 19
17
13 を挿入
根 根
2 分探索木へデータを挿入
31
2 分探索木へのデータ挿入
2 分探索木へ点を 1 つ追加する(※ 2 分探索木の性質が失われないように!)
12
5 18
2 9 15 19
17
アルゴリズム
(根からスタートして)現在の頂点のキーと k を比較
キー k の方が大きい → 右の子へ移動
キー k の方が小さい → 左の子へ移動
右の子が NULL ならば , ここに挿入繰り返し
左の子が NULL ならば , ここに挿入
13
根
挿入の擬似コード
32
TREE-INSERT(k)1 Creat a new vertex z
with key[z] ← k, left[x] ← NULL, right[x] ← NULL
2 y ← NULL, x ← root
3 while x ≠ NULL
4 do y ← x
5 if key[z] < key[x]
6 then x ← left[x]
7 else x ← right[x]
8 p[z] ← y
9 if y = NULL // 2 分木が空だったとき10 then root ← z
11 else if key[z] < key[y]
12 then left[y] ← z
13 else right[y] ← z
12
5 18
2 9 15 19
1713
根( = root )
x: 2 分探索木上の頂点
key[x]: 頂点 x がもつキーleft[x]: 頂点 x の左の子right[x]: 頂点 x の右の子
root: 2 分探索木の根
k = 13 の例:
xy = NULL
x
y
x
y
x
y
p[x]: 頂点 x の親
目次 : 今日やること
木構造 2 分木・ 2 分探索木
2 分探索 頂点の挿入 頂点の削除
木の頂点の番号づけ トライ・サフィックス木(の紹介だけ)
33
7
6
10 13
2 分探索木からデータを削除
34
2 分探索木からデータ削除
2 分探索木へ点を 1 つ削除する(※ 2 分探索木の性質が失われないように!)
15
5 16
3 12
18
20
23
根( = root )
13 を削除
1 2
7
6
10
15
5 16
3 12
18
20
23
根( = root )
1 2
なくなってる !!!
13
削除の難しさ
2 分探索木からデータ削除
2 分探索木へ点を 1 つ削除する(※ 2 分探索木の性質が失われないように!)
探索・挿入と比べるとちょっと難しい
6
10 13
35
15
5 16
3 12
18
20
23
5 を削除
1 2
6
10
15
16
3 12
18
20
231 2
ここの穴埋め
どうする !?
ポイントとなるアイデア
2 分探索木からデータ削除
2 分探索木へ点を 1 つ削除する(※ 2 分探索木の性質が失われないように!)
探索・挿入と比べるとちょっと難しい
36
ポイント子の個数で 3 つに場合分けして考
える Case 1: 子の個数が0Case 2: 子の個数が 1
Case 3: 子の個数が2
Case 1: 子の個数が 0 (簡単 ! )
削除の仕方
(削除したい頂点を z とする)
37
1. z を削除
7
6
10 13
15
5 16
3 12
18
20
23
根( = root )
13 を削除
1 2
7
6
10
15
5 16
3 12
18
20
23
根( = root )
1 2
Case 2: 子の個数が 1 (これも簡単 ! )
削除の仕方
(削除したい頂点を z とする)
38
1. z の子と z の親を繋げる2. z を削除
7
6
10 13
15
5 16
3 12
18
20
23
根( = root )
16 を削除
1 2
7
6
10
15
5
3 12 18
20
23
根( = root )
1 2
7
Case 3: 子の個数が 2 (ちょいムズ)
39
6
10 13
15
5 16
3 12
18
20
23
5 を削除
1 2
方針: z を削除し、 z の successor に穴埋めさせる削除の仕方
(削除したい頂点を z とする)1. key[z] の次に大きいキーをもつ頂点を探す( y とする)2. y をいったん削除3. x を y に置き換える
z の successor
7
10 13
15
6 16
3 12
18
20
231 2
(削除後も , ちゃーんと 2 分木の性質を満たしてます)
目次 : 今日やること
木構造 2 分木・ 2 分探索木
2 分探索 頂点の挿入 頂点の削除
木の頂点の番号づけ
40
木の頂点の番号づけ( 3 種類)
41
12
5 18
2 9 15 19
17
1. preorder (先行順)
例: 12, 5, 2, 9, 18, 15, 17, 19
3. postorder (後行順)
例: 2, 9, 5, 17, 15, 19, 18, 12
2. inorder (中間順)
例 : 2, 5, 9, 12, 15, 17, 18, 19
深さ優先探索で , 訪れた順に番号づけ
深さ優先探索で , 左子から戻ってきたときに番号づけ(注意: 2 分木だけに定義される番号づけです)
深さ優先探索で , 最後に去っていく順に番号づけ
(課題に出します)
木の頂点の番号づけ( 3 種類)
42
12
5 18
2 9 15 19
17
1. preorder (先行順)
例: 12, 5, 2, 9, 18, 15, 17, 19
深さ優先探索で , 訪れた順に番号づけ
(課題に出します)
A
B C
Search(A) 1.Mark A; 2.if ( A is leaf )
return;3.Search(B); 4.Search(C);
深さ優先探索(depth-first search)
43
12
5 18
2 9 15 19
17
(課題に出します)
A
B C
Search(A) 1.Search(B); 2.Mark A;3.Search(C);
// modify it // if A is a leaf.
44
12
5 18
2 9 15 19
17
(課題に出します)
A
B C
Search(A) 1.Search(B); 2.Search(C);3.Mark A;
// modify it // if A is a leaf.
第 1 回 レポート課題課題 1
O(n^2) sort, O(n lg n) sort を作り, n = 10 から 10^4 まで実行時間を測定してみよ.整数配列の sort で良い.
** copy paste でも今回だけは良いが 擬似コードで 分かれば 自由に 書けるはずだ.
Free Yourself
でも 行き詰ったら 基礎1 TA メーリングリストへ. [email protected]提出: IS棟2F事務室ポストへ.コードと測定結果をA4印刷.
出題日 : 2013/May 1締切日 : 2013/May 15
第 2 回 レポート課題
.2 分探索木の全キーを preorder で出力するプログラムを作成してください . 余裕のある人は inorder, postorder についても同様にプログラムを作成してください。
課題2.
2 9
12
5 18
15 19
17
12, 5, 2, 9, 18, 15, 17, 19
左の 2 分木の全キーをpreorder で出力
Hint: 再帰呼出を使うと 楽に作れる
出題: H25年 5月 1 日締切: 同年 5月 22 日まで.提出先:IS棟2F事務ポスト ( コード,実行結果をA4 用紙に出力,簡単にコメントをつける)
47
このスライドは 2010年に山中先生が作成したものを今回 大森が改訂しました.木の深さ優先探索,幅優先探索は独自作成です. これから面白いところで 交代.
アルゴリズムの設計と解析 ( 上 )( 下 ) Aho, Hopcroft, Ullman, サイエンス社が ほぼ全ての古典的教科書の源.
MIT本 ( コルメン著 ) – 分厚い.翻訳が下手.Knuth本 – 難しいが Bible なので仕方ない. 基本とは難しいものだと分かる.「データ構造」(星守 著,昭晃堂) -- 数理工学科向きのアルゴリズム講義の 教科書. 見た目よりも お勧め.