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