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.
左子ノードを再帰的に削除
右子ノードを再帰的に削除
自身のノードを削除