講義資料ppt

Download Report

Transcript 講義資料ppt

アルゴリズムと
データ構造
第14回
木構造
木構造

木
 階層的な関係を表現するデータ構造
 ノード(節)を枝で結んだ構造
木構造

木
 根(root)
最も上流のノード
 1つの木には1つのみ存在

 葉(leaf)・終端節・外部節

最下流のノード
 非終端節・内部節

葉以外のノード
木構造

木
 子(child)

あるノードから見て下流側のノード
いくつでも持てる
 最下流の葉は子を持たない

 親(parent)

あるノードから見て上流側のノード
各ノードごとに1つのみ
 根には親はなし

木構造

木
 兄弟(sibling)

共通の親を持つノード
 先祖(ancestor)

あるノードから上流側にたどれる全てのノード
 子孫(descendant)

あるノードから下流側にたどれる全てのノード
木構造

木
 レベル(level)

親からどれくらい離れているかを示す

親がレベル0
 度数(degree)

各ノードが持つ子の数

すべてのノードの度数がn以下である木:n進木
木構造

木
 高さ(height)

葉のレベルの最大値
 部分木(subtree)

あるノードを根とし、その子孫で構成される木
 空目(null

tree)
ノードや枝がまったく存在しない木
木構造

木
ノード
レベル0
葉
レベル1
部分木
枝
X
葉
葉
根
葉
葉
葉
葉
葉
レベル2
レベル3
木構造

順序木と無順序木
 兄弟関係にあるノードに
順序関係を有する:順序木
 順序関係を有しない:無順序木

X
Y
順序木としては違う木
・ YとZの位置が逆
X
Z
Z
Y
無順序木としては同じ木
・ 全ノードの要素・親子関係が同じ
木構造

順序木の探索
 横型探索(幅優先順探索)
レベルの低い点から開始、左から右へ順次探索
 終わると次のレベルへ

 縦型探索(深さ優先順探索)
まず葉に到達するまで枝を下るのを優先して探索
 葉に到達したら1つ親に戻って次のノードへ

木構造

木の探索
 縦型探索の種類

行きがけ順


通りがけ順


ノードに立ち寄る→左部分木をなぞる→右部分木をなぞる
左部分木をなぞる→ノードに立ち寄る→右部分木をなぞる
帰りがけ順

左部分木をなぞる→右部分木をなぞる→ノードに立ち寄る
木構造

木の探索
横型探索
A
B
C
D
E
H
A
B
I
C
D
F
J
E
F
K
G
G
L
H
I
J
K
L
木構造

木の探索
縦型探索:行きがけ順
A
B
C
D
E
H
A
B
I
D
H
F
J
E
I
K
J
G
L
C
F
K
L
G
木構造

木の探索
縦型探索:通りがけ順
A
B
C
D
E
H
H
D
I
B
I
F
J
E
J
K
A
G
L
K
F
L
C
G
木構造

木の探索
縦型探索:帰りがけ順
A
B
C
D
E
H
H
D
I
I
J
F
J
E
B
G
K
K
L
L
F
G
C
A
2分木と2分探索木

2分木
 木上のノードが左の子と右の子を持つ木
左右の子が区別される:2進木ではない
 左の子、右の子のいずれか、または両方ともなくても可

 部分木
左の子を根とする部分木:左部分木
 右の子を根とする部分木:右部分木

2分木と2分探索木

完全2分木
 根から下方レベルへ、かつ同一レベル内では左か
ら右へ、ノードが空くことなく詰まっている2分木
最下流でないレベルは全ノードが詰まる
 最下流レベルでは左側から詰まる


途中まででもよい
 横型探索の走査順を配列の添え字に対応可能

ヒープソートなどで利用
2分木と2分探索木

2分探索木
 すべてのノードで
その左部分木のノードのキー値が、そのキー値より小
 その右部分木のノードのキー値が、そのキー値より大

となっている2分木
 通りがけ順でなぞると、昇順で値が得られる
2分木と2分探索木

2分探索木
10
5
15
4
7
1
1
4
6
5
6
12
9
7
9
11
10
20
14
11
12
14
15
20
2分木と2分探索木

2分探索木の実現
typedef struct __bnode {
Member data;
struct __bnode *left;
struct __bnode *right;
} BinNode;
/* データを格納する構造体 */
/* 左子ノードへのポインタ */
/* 右子ノードへのポインタ */
・ 子ノードがない場合、left、rightはNULL
・ データ中どれか1つをキー値として定める必要あり
2分木と2分探索木

2分探索木の実現
 ノードの探索

根から探索、探索するキー値と各ノードのキー値を比較
探索するキー値の方が小さければ左子ノードと比較
 探索するキー値の方が大きければ右子ノードと比較


順次子ノードを探索
見つかれば探索成功
 見つからずに葉に到達したら探索失敗

2分木と2分探索木

2分探索木の実現
ノードの探索:3を探索
5
2
7
1
4
3
3の方が大きい:右へ
3の方が小さい:左へ
3と一致:探索成功
2分木と2分探索木

2分探索木の実現
ノードの探索:8を探索
5
2
7
1
4
3
8の方が大きい:右へ
子ノードなし:探索失敗
2分木と2分探索木

2分探索木の実現
 ノードの探索の実装

左右子ノードの探索に再帰を利用
探索するキー値とノードのキー値を比較
 探索するキー値の方が小さければ左子ノードを再帰探索
 探索するキー値の方が大きければ右子ノードを再帰探索
 自身がNULLなら子ノードなしなので探索失敗

2分木と2分探索木

2分探索木の実現
 ノードの挿入

まず、挿入すべきデータと同じキー値を持つノードがあ
るか探索


すでに同じキー値を持つノードがあったら挿入中止
探索失敗箇所にノードを新たに作成し、データ挿入
2分木と2分探索木

2分探索木の実現
ノードの挿入:1を挿入
ノードの挿入:5を挿入
ノードの挿入:9を挿入
ノードの挿入:3を挿入
6
2
7
1
4
3
9
5
1の方が小さい:左へ
ノードなし:ここへ追加
5の方が小さい:左へ
3の方が小さい:左へ
9の方が大きい:右へ
5の方が大きい:右へ
3の方が大きい:右へ
2分木と2分探索木

2分探索木の実現
 ノードの挿入の実装

ノードの探索と類似:再帰を利用
挿入するデータのキー値とノードのキー値を比較
 一致したら挿入中止
 挿入するデータのキー値の方が小さければ左子ノードに
再帰挿入処理
 挿入するデータのキー値の方が大きければ右子ノードに
再帰挿入処理
 自身がNULLなら挿入場所なので挿入

2分木と2分探索木

2分探索木の実現
 ノードの削除

3通りのケースで場合分け
子ノードを持たないノードの削除
 1つだけ子ノードを持つノードの削除
 2つの子ノードを持つノードの削除

2分木と2分探索木

2分探索木の実現
 子ノードを持たないノードの削除

該当ノードの親ノードが子を持たないようにする
削除ノードが親ノードの左の子:親の左ポインタNULL
 削除ノードが親ノードの右の子:親の右ポインタNULL

2分木と2分探索木

2分探索木の実現
 1つだけ子ノードを持つノードの削除

削除するノードの位置に子ノードが配置されるように、ポ
インタを付け替え
削除ノードが親ノードの左の子:親ノードの左ポインタが削除
ノードの子をさすよう設定
 削除ノードが親ノードの右の子:親ノードの右ポインタが削除
ノードの子をさすよう設定

2分木と2分探索木

2分探索木の実現

2つの子ノードを持つノードの削除

削除ノードの左部分木の中で最大キー値を持つノード
が、削除位置に来るようにポインタを付け替え
1.
2.
3.
削除ノードの左部分木からキー値が最大のノードを探索
探索したノードを削除位置に移動
移動前にあった探索ノードを削除
2分木と2分探索木

2分探索木の実現

全ノードの表示


通りがけ順で表示することで昇順に表示
全ノードの表示の実装
1.
2.
3.
左子ノードを再帰的に表示
自身のノードを表示
右子ノードを再帰的に表示
2分木と2分探索木

2分探索木の実現

全ノードの削除

帰りがけ順で各ノードを削除


さもないと子ノードを削除する前に親ノードが消滅
全ノードの削除の実装
1.
2.
3.
左子ノードを再帰的に削除
右子ノードを再帰的に削除
自身のノードを削除