アルゴリズムとデータ構造 Contents of this lecture 木の性質 Example

Contents of this lecture

アルゴリズムとデータ構造


復習:木の性質、木の走査
応用:2分探索木
木の他の実現方法
第7回講義:木構造その2
Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)
1
Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)
Example
木の性質
1.
2.
3.
4.
木において、任意の2つのノードを結ぶパスはただ1つ
である.
ノードの個数がNである木には、辺がN‐1個ある.
中間ノードがNである2分木には、N+1個終端ノードが
ある.
内部ノードがNである2分木が一杯になっていれば、そ
の高さは約log2Nである.

下の木について、1番と2番目の性質を確かめよ
E
A
A
R
S
3
E
T
M
Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)
2
P
L
E
Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)
4
1
Example

木の走査 (traverse)
下の2分木について、3番と4番目の性質を確
かめよ





Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)
5
初期化と中央順走査のプログラム例
treeprint() {
treeprintr(head->r);
}
treeprintr(struct node *x){
if (x != z) {
treeprintr(x->l);
printnode(x);
treeprintr(x->r);
}
}
Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)
Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)
6
Example
(pp. 16-17 in text, Vol. 2)
treeinitialize() {
z = (struct node *)
malloc(sizeof *z);
z->l = z; z->r = z; z->info = -1;
head = (struct node *)
malloc(sizeof *head);
head->r = z; head->key = 0;
}
走査:ノードをすべて訪れること.
先行順:ルートから始まり、現在ノードを先に処理し、次に
左ノードと右ノードの順に再帰的に処理する.
中央順:ルートから始まり、左ノード、現在ノード、右ノード
の順に再帰的に処理する.
後行順:ルートから始まり、左ノード、右ノード、現在ノード
の順に再帰的に処理する.
レベル順:(再帰的でない)上から下へ、左から右へ、レ
ベル毎にそのレベルにあるノードを順番に処理する.

以下の2分木を、先行順、中央順、後行順、レベル順
のそれぞれによって、ノードに訪れる順番を考えよ
P
M
S
A
L
E
A
R
E
T
E
7
Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)
8
2
2分探索木 (binary search tree)





2分探索木の特徴
探索:前もって格納されている多くのデータの中
から望みのデータを引き出す操作.
探索の目的:与えられた探索キーと一致する
キーをもつすべてのレコードを見つけ出し、必要
なレコード内のデータを引き出す.
2分探索木を使えば、効率的に探索できる.
与えられたキーを最初にルートにあるキーと比
較し、小さければ左部分木に行き、等しい時は停
止し、大きい時には右部分木に行く.
以上を再帰的に適用する.
Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)




9
探索のプログラム例
static struct node {
int key, info;
struct node *l, *r; };
static struct node *t, *head, *z;
int treesearch(int v) {
struct node *x = head->r;
z->key = v;
while (v != x->key)
x = (v < x->key) ? x->l : x->r;
return x->info;
}
単純で効率のよい動的な探索法で、もっと
も基本的なアルゴリズムの1つである。
ノードにおかれたキーより、
小さいキーをもつレコードはすべてそのノード
の左部分木の中にあり、
大きいあるいは等しいキーをもつレコードはす
べて右部分木にある。
Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)
探索の様子
•
ダミーノードの使い方
•
終了条件
•
探索の成功条件
•
再帰のやりかた

2分探索木におけるIの探索
A
S
E
A
R
C
See p. 15, Vol. 2
Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)
10
11
H
Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)
12
3
An Example
データの挿入(p. 17 in text, Vol. 2)
treeinsert(int v, int info) {
struct node *p, *x;
p = head; x = head->r;
while (x != z) {
p = x; x = (v < x->key) ? x->l : x->r;
}
x = (struct node *) malloc(sizeof *x);
x->key = v; x->info = info; x->l = z; x->r = z;
if (v < p->key) p->l = x; else p->r =x;
}
Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)

A
S
E
A

13



H
Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)
14
2分探索木の計算量
探索、挿入などより実現しにくい
方法:3つのケースに分けて考える

R
C
2分探索木の削除

ASEARCHINGEXAMPLE

子を持たない→そのまま削除
子を1つもつ→削除された親ノードを子ノードで置きかえ
子を2つもつ→削除された親ノードを、左部分木の最大
ノードかあるいは右部分木の最小ノードで置きかえ

N個のランダムなキーから生成された2分
探索木での1回の探索または挿入
 平均約log2N回の比較
N個のデータからなる2分探索木での探索

最悪の場合にはN回の比較
コードは第2巻の22ページにある
Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)
15
Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)
16
4
木の他の実現方法-1

リンクは子供たちではなく、子供と兄弟
A
A
木の他の実現方法-2
Son
E
Brother
R
S
k
1
2
3
4
5
6
7
8
9
10 11
a[k]
A
S
A
M
P
L
E
T
R
E
E
dad[k]
3
3
11
8
8
8
8
9
11
11
--
E
E
T
M
P
A
L
A
E
Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)
17
L
クイズ(2)
次のデータを順番に空の木に入れて
いった場合に、作られる木を書きなさ
い。ただし、途中の過程も書くこと。

木にデータを入れていく(アルゴリズム
C 第2巻 p.18)ときは、まず木を辿って
空いている所(葉)を探し、見つかった
らそこにデータを入れます。木を辿ると
きに、左右どちらに行くかは、入れたい
データがそのノードの値よりも大きいか
小さいかで決めます。右の図を参考に
して書いてみてください。
Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)
P
E



19
配列実現であり、
親ノードのインデックス
だけを記憶しておく
E
Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)
OLDFASHION

S
M
Quiz(1)

R
T
18
inorder(struct node *t){
if(t->l != z) inorder(t->l);
visit(t);
if(t->r != z) inorder(t->r);
}
クイズ(1)で作られた木を inorder でトラバースし
た結果を書きなさい。
演習第 6 回でやった inorder でトラバースして
みてください。
正しく木が作れていて、正しくトラバースできれば、
アルファベット順に並んでいるはずです。
上の例では A I K N O になります。
Produced by Qiangfu Zhao (Since 2009), All rights reserved (c)
20
5