Taro-2分探索木Ⅰ(公開版).jtd

Similar documents
Taro-2分探索木Ⅱ(公開版).jtd

Taro-リストⅠ(公開版).jtd

Taro-リストⅢ(公開版).jtd

Microsoft PowerPoint - kougi10.ppt

Taro-スタック(公開版).jtd

memo

Microsoft Word - 13

Microsoft PowerPoint - kougi11.ppt

Microsoft Word - no206.docx

Taro-ポインタ変数Ⅰ(公開版).j

Microsoft PowerPoint - 05.pptx

memo

Microsoft Word - 12

第2回

Taro-再帰関数Ⅲ(公開版).jtd

Taro-再帰関数Ⅱ(公開版).jtd

PowerPoint プレゼンテーション

プログラミングI第10回

Microsoft PowerPoint - 06.pptx

始めに, 最下位共通先祖を求めるための関数 LcaDFS( int v ) の処理を記述する. この関数は値を返さない再帰的な void 関数で, 点 v を根とする木 T の部分木を深さ優先探索する. 整数の引数 v は, 木 T の点を示す点番号で, 配列 NodeSpace[ ] へのカーソル

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

PowerPoint プレゼンテーション

Microsoft PowerPoint - 7.pptx

Microsoft Word - NonGenTree.doc

Taro-最大値探索法の開発(公開版

alg2015-6r3.ppt

memo

Taro-プログラミングの基礎Ⅱ(公

PowerPoint Presentation

Microsoft PowerPoint - algo ppt [互換モード]

LIFO(last in first out, ) 1 FIFO(first in first out, ) 2 2 PUSH POP : 1

Microsoft PowerPoint - 11.pptx

Microsoft PowerPoint - kougi9.ppt

二分木の実装

PowerPoint Template

untitled

C言語によるアルゴリズムとデータ構造

I. Backus-Naur BNF S + S S * S S x S +, *, x BNF S (parse tree) : * x + x x S * S x + S S S x x (1) * x x * x (2) * + x x x (3) + x * x + x x (4) * *

memo

Microsoft Word - Cプログラミング演習(10)

I. Backus-Naur BNF : N N 0 N N N N N N 0, 1 BNF N N 0 11 (parse tree) 11 (1) (2) (3) (4) II. 0(0 101)* (

Microsoft PowerPoint - algo ppt [互換モード]

Taro-ファイル処理(公開版).jtd

< F2D837C E95CF CF68A4A94C5816A2E6A>

第2回

次に示す数値の並びを昇順にソートするものとする このソートでは配列の末尾側から操作を行っていく まず 末尾の数値 9 と 8 に着目する 昇順にソートするので この値を交換すると以下の数値の並びになる 次に末尾側から 2 番目と 3 番目の 1

Taro-数値計算の基礎Ⅱ(公開版)

kiso2-09.key

[Problem F] 古い記憶 良さそうな方法は思いつかなかった アイディア募集中!!! かなり強引に解いている 各判定データに対して 30 秒程度かかる 元の文章と改ざん文章の関係を考える ウィルス感染の可能性は高々 2 回であり 各々の感染では 1 文字削除 1 文字追加 1 文字変更が行われ

Microsoft PowerPoint - 12.ppt [互換モード]

Microsoft Word - Cプログラミング演習(11)

Microsoft PowerPoint - lec10.ppt

memo

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

Microsoft PowerPoint - kougi2.ppt

PowerPoint プレゼンテーション

画像ファイルを扱う これまでに学んだ条件分岐, 繰り返し, 配列, ファイル入出力を使って, 画像を扱うプログラムにチャレンジしてみよう

Microsoft PowerPoint - 13.ppt [互換モード]

Microsoft Word - 3new.doc

Microsoft Word - Cプログラミング演習(12)

memo

演習課題No12

Prog1_15th

PowerPoint Presentation

Microsoft Word - no205.docx

Microsoft Word - 中間試験 その1_解答例.doc

II 3 yacc (2) 2005 : Yacc 0 ~nakai/ipp2 1 C main main 1 NULL NULL for 2 (a) Yacc 2 (b) 2 3 y

Microsoft Word - no15.docx

cp-7. 配列

文字数は1~6なので 同じ本数の枝を持つパスで生成される呪文の長さは最大で6 倍の差がある 例えば 上図のようなケースを考える 1サイクル終了した時点では スター節点のところに最強呪文として aaaaaac が求まる しかしながら サイクルを繰り返していくと やがてスター節点のところに aaaaaa

PowerPoint Presentation

演算増幅器

Microsoft Word - 第5回 基本データ構造2(連結リスト).doc

情報処理演習 B8クラス

Microsoft PowerPoint - CproNt02.ppt [互換モード]

ポインタ変数

C のコード例 (Z80 と同機能 ) int main(void) { int i,sum=0; for (i=1; i<=10; i++) sum=sum + i; printf ("sum=%d n",sum); 2

:30 12:00 I. I VI II. III. IV. a d V. VI

r07.dvi

:30 12:00 I. I VI II. III. IV. a d V. VI

ohp07.dvi

第3回 配列とリスト

Taro-再帰関数Ⅰ(公開版).jtd

Microsoft PowerPoint - guidance.ppt

char int float double の変数型はそれぞれ 文字あるいは小さな整数 整数 実数 より精度の高い ( 数値のより大きい より小さい ) 実数 を扱う時に用いる 備考 : 基本型の説明に示した 浮動小数点 とは数値を指数表現で表す方法である 例えば は指数表現で 3 書く

2006年10月5日(木)実施

講習No.12

2018年度「プログラミング言語」配布資料 (12)

Taro-ビット処理(公開版).jtd

Microsoft PowerPoint - prog04.ppt

プログラミング方法論 II 第 14,15 回 ( 担当 : 鈴木伸夫 ) 問題 17. x 座標と y 座標をメンバに持つ構造体 Point を作成せよ 但し座標 は double 型とする typedef struct{ (a) x; (b) y; } Point; 問題 18. 問題 17 の

プログラミング実習I

Microsoft Word - Cプログラミング演習(9)

オートマトンと言語

Microsoft PowerPoint - 10.ppt [互換モード]

I ASCII ( ) NUL 16 DLE SP P p 1 SOH 17 DC1! 1 A Q a q STX 2 18 DC2 " 2 B R b

プログラミング基礎

今回のプログラミングの課題 ( 前回の課題で取り上げた )data.txt の要素をソートして sorted.txt というファイルに書出す ソート (sort) とは : 数の場合 小さいものから大きなもの ( 昇順 ) もしくは 大きなものから小さなもの ( 降順 ) になるよう 並び替えること

‚æ4›ñ

Microsoft Word - no12.doc

Transcription:

2 分探索木 Ⅰ 0. 目次 1. 2 分探索木とは 2. 2 分探索木の作成 3. 2 分探索木の走査 3. 1 前走査 3. 2 中走査 3. 3 問題 問題 1 問題 2 後走査 4. 2 分探索木の表示 - 1 -

1. 2 分探索木とは 木はいくつかの節点と節点同士を結ぶ辺から構成される 2 つの節点 u,v が直接辺で結ばれているとき 一方を親節点 他方を子節点という ある節点の親節点は高々 1 つであり 子節点は 0 個以上である 節点の中には 親節点をもたない節点がただ 1 つあり 根という また 子節点をもたない節点を葉という 木は つぎのように定義される ( 1 ) ひとつの節点は 木である ( 2 ) v が節点で T 1,T 2,,T k が木で それぞれの木の根が v 1,v 2,,v k とする このとき v を v 1,v 2,,v k の親とするのは 木である 節点 v 1,v 2,,v k は節点 v の子と呼ばれる v v 1 v 2 v k T 1 T k T 2 2 分木は どの節点も高々 2 個の子節点をもつ 2 個の子節点の内 左に書かれる子節点を根とする部分木を左部分木 右に書かれる子節点を根とする部分木を右部分木という A B C D E F G H 節点 : A, B, C, D, E, F, G, H ( A は根でもある ) 辺 : A B, A C, B D, B E, C F, F G, F H ( X Y のとき X が親 Y が子を意味する ) 2 分木の節点に集合 S の要素を割り当てる 各節点において 割り当てられた要素の大きさが 左部分木のどの節点の要素よりも大きく 右部分木のどの節点 の要素よりも小さいとき 2 分探索木という - 2 -

2. 2 分探索木の作成 空の 2 分探索木から始める 挿入する要素と節点の要素を比較し 前者が小さい場合 左部分木に追加し 前者が大きい場合 右部分木に追加していく 手順 9 個のデータ (55,33,11,99,44,77,22,66,88) で手順を示す ( 1 ) ( 2 ) ( 3 ) 55 55 55 33 33 ( 4 ) ( 5 ) 55 55 33 99 33 99 11 11 44 ( 6 ) ( 7 ) 55 55 33 99 33 99 11 44 77 11 44 77 ( 8 ) ( 9 ) 55 55 33 99 33 99 11 44 77 11 44 77 22 66 22 66 88 2 分探索木を表現するために データを保存する変数 info 左部分木を指すポインタ left 右部分木を指すポインタ right をもつ構造体を用意する 根を指すポインタ変数を root とする ポインタ変数 root は空の同じ構造体を指す このようにすると プログラムが簡潔になる 22 11 B root A C D E B NULL A NULL D NULL NULL C NULL NULL E NULL - 3 -

プログラム 非再帰版 ( bt211.c) 1 /* << bt211.c >> */ 2 /* 2 分探索木の作成 */ 3 #include <stdio.h> 4 #include <stdlib.h> 5 struct NODE { 6 int info; /* 節点がもつデータ */ 7 struct NODE *left; /* 左の子節点を指すポインタ */ 8 struct NODE *right; /* 右の子節点を指すポインタ */ 9 }; 10 struct NODE *mktree(); 11 12 int main() { 13 struct NODE *root; 14 15 /* 2 分探索木の作成 */ 16 root = mktree(); 17 } 18 19 /* 2 分探索木の作成 */ 20 struct NODE *mktree() { 21 int data; 22 struct NODE *p, /* 現節点を指すポインタ変数 */ 23 *q, /* 現節点の親節点を指すポインタ変数 */ 24 *r, /* 作業用ポインタ変数 */ 25 *root; /* 根を指すポインタ変数 */ 26 27 /* 根を指すポインタ変数と空の構造体の作成 */ 28 root = (struct NODE *)malloc(sizeof(struct NODE)); 29 root->left = NULL; 30 root->right = NULL; 31 32 while( 1 ) { 33 /* データの読み込み */ 34 scanf("%d",&data); 35 if( data <= 0 ) { break; } 36 r = (struct NODE *)malloc(sizeof(struct NODE)); 37 r->info = data; 38 r->left = NULL; 39 r->right = NULL; 40 41 root->info = data; /* 2 分探索木にデータを追加するとき 42 空の構造体の左部分木に追加できるように 43 root->info=data としておく */ 44 /* 初期設定 */ 45 p = root->left; 46 q = root; 47 48 /* 追加する場所を探す */ 49 while( p!= NULL ) { 50 /* 重複データは追加しない */ 51 if( data == p->info ) { goto next; } 52-4 -

53 /* データ dataが現在の節点のデータ (p->info) 以下のとき 54 左部分木へ 大きいとき右部分木へ移動する */ 55 q = p; 56 if( data <= p->info ) { 57 p = p->left; 58 } else { 59 p = p->right; 60 } 61 } 62 63 /* データの追加 */ 64 if( data <= q->info ) { 65 /* 左部分木として追加 */ 66 q->left = r; 67 } else { 68 /* 右部分木として追加 */ 69 q->right = r; 70 } 71 next:; 72 } 73 return root; 74 } - 5 -

3. 2 分探索木の走査 2 分探索木の辺を反時計回りに ( 赤い線に沿って ) なぞっていくと 2 分探索木のすべての節点を訪問できる A B C D E F G H 2 分探索木のすべての節点をたどる方法として 前走査 中走査 後走査の 3 通り考えられる 前走査 : まず 親節点を訪問する つぎに 左部分木のすべての節点を訪問する 最後に 右部分木のすべての節点を訪問する 1 A 2 B 5 C 3 D 4 E 6 F 7 G 8 H 訪問順 : A B D E C F G H - 6 -

中走査 : まず 左部分木のすべての節点を訪問する つぎに 親節点を訪問する 最後に 右部分木のすべての節点を訪問する 4 A 2 B 5 C 1 D 3 E 7 F 6 G 8 H 訪問順 : D B E A C G F H 後走査 : まず 左部分木のすべての節点を訪問する つぎに 右部分木のすべての節点を訪問する 最後に 親節点を訪問する 8 A 3 B 7 C 1 D 2 E 6 F 4 G 5 H 訪問順 : D E B G H F C A - 7 -

3. 1 前走査 プログラム 再帰版 (bt311.c) 1 /* << bt311.c >> */ 2 /* 2 分探索木の走査 ( 前走査 ) */ 3 #include <stdio.h> 4 #include <stdlib.h> 5 struct NODE { 6 int info; /* 節点がもつデータ */ 7 struct NODE *left; /* 左の子節点を指すポインタ */ 8 struct NODE *right; /* 右の子節点を指すポインタ */ 9 }; 10 void preorder(struct NODE *p); 11 struct NODE *mktree(); 12 13 int main() { 14 struct NODE *root; 15 16 /* 2 分探索木の作成 */ 17 root = mktree(); 18 19 /* 前走査 */ 20 preorder(root->left); printf("\n"); 21 } 22 23 /* 前走査 */ 24 void preorder(struct NODE *p) { 25 if( p == NULL ) { return; } 26 printf(" %d",p->info); 27 preorder(p->left); 28 preorder(p->right); 29 } - 8 -

実行結果 % cc bt311.c 55 22 88 11 33 77 99 44 66 0 55 22 11 33 44 88 77 66 99 1 55 2 22 6 88 3 11 4 33 7 77 9 99 5 44 8 66 1 から 9 の順に訪問する 11 22 33 44 55 66 77 88 99 0 11 22 33 44 55 66 77 88 99 99 88 77 66 55 44 33 22 11 0 99 88 77 66 55 44 33 22 11 22 11 55 44 33 99 88 77 66 0 22 11 55 44 33 99 88 77 66-9 -

3. 2 中走査 プログラム 再帰版 ( bt321.c) 1 /* << bt321.c >> */ 2 /* 2 分探索木の走査 ( 中走査 ) */ 3 #include <stdio.h> 4 #include <stdlib.h> 5 struct NODE { 6 int info; /* 節点がもつデータ */ 7 struct NODE *left; /* 左の子節点を指すポインタ */ 8 struct NODE *right; /* 右の子節点を指すポインタ */ 9 }; 10 void inorder(struct NODE *p); 11 struct NODE *mktree(); 12 13 int main() { 14 struct NODE *root; 15 16 /* 2 分探索木の作成 */ 17 root = mktree(); 18 19 /* 中走査 */ 20 inorder(root->left); printf("\n"); 21 } 22 23 /* 中走査 */ 24 void inorder(struct NODE *p) { 25 if( p == NULL ) { return; } 26 inorder(p->left); 27 printf(" %d",p->info); 28 inorder(p->right); 29 } - 10 -

実行結果 % cc bt321.c 55 22 88 11 33 77 99 44 66 0 11 22 33 44 55 66 77 88 99 5 55 2 22 8 88 1 11 3 33 7 77 9 99 4 44 6 66 1 から 9 の順に訪問する 11 22 33 44 55 66 77 88 99 0 11 22 33 44 55 66 77 88 99 99 88 77 66 55 44 33 22 11 0 11 22 33 44 55 66 77 88 99 22 11 55 44 33 99 88 77 66 0 11 22 33 44 55 66 77 88 99-11 -

3. 3 問題 問題 1 後走査 プログラム 再帰版 ( bt331.c) 1 /* << bt331.c >> */ 2 /* 2 分探索木の走査 ( 後走査 ) */ 3 #include <stdio.h> 4 #include <stdlib.h> 5 struct NODE { 6 int info; /* 節点がもつデータ */ 7 struct NODE *left; /* 左の子節点を指すポインタ */ 8 struct NODE *right; /* 右の子節点を指すポインタ */ 9 }; 10 void postorder(struct NODE *p); 11 struct NODE *mktree(); 12 13 int main() { 14 struct NODE *root; 15 16 /* 2 分探索木の作成 */ 17 root = mktree(); 18 19 /* 後走査 */ 20 postorder(1 ); printf("\n"); 21 } 22 23 /* 後走査 */ 24 void postorder(struct NODE *p) { 25 if( p == 2 ) { return; } 26 postorder(3 ); 27 postorder(4 ); 28 printf(" %d",p->info); 29 } - 12 -

実行結果 % cc bt331.c 55 22 88 11 33 77 99 44 66 0 11 44 33 22 66 77 99 88 55 9 55 22 4 8 88 1 11 3 33 6 77 7 99 2 44 5 66 1 から 9 の順に訪問する 11 22 33 44 55 66 77 88 99 0 99 88 77 66 55 44 33 22 11 99 88 77 66 55 44 33 22 11 0 11 22 33 44 55 66 77 88 99 22 11 55 44 33 99 88 77 66 0 11 33 44 66 77 88 99 55 22-13 -

問題 2 読み込んだデータから 2 分探索木を構成し 前走査 中走査 後走査でたどる順を示せ 例入力データ : 55 22 88 11 33 77 99 44 66 前走査 : 55 22 11 33 44 88 77 66 99 中走査 : 11 22 33 44 55 66 77 88 99 後走査 : 11 44 33 22 66 77 99 88 55 ( 1 ) 入力データ : 44 11 33 77 66 55 99 88 22 前走査 中走査 後走査 5 6 7-14 -

4. 2 分探索木の表示 2 分探索木を Excel のグラフ機能を使って表示する まず 各節点に座標を割り当てる 節点が交わらないように下図のように座標を決める 根の座標は (0,0) とする (0,0) (-1/2,-1) (1/2,-1) (-3/4,-2) (-1/4,-2) (1/4,-2) (3/4,-2) すなわち 2 分探索木の深さが一つ増えるごとに 節点間の幅を 1/2 倍にする このプログラムで 節点の座標を求める ただし Excel のグラフ機能 ( 散布図 ) を使って表示するため 前走査で節点を通過するたびに座標を出力する プログラム 再帰版 ( bt411.c) 1 /* << bt411.c >> */ 2 /* 2 分探索木の走査 ( 前走査 ) */ 3 /* 節点の座標を出力する */ 4 #include <stdio.h> 5 #include <stdlib.h> 6 struct NODE { 7 int info; /* 節点がもつデータ */ 8 struct NODE *left; /* 左の子節点を指すポインタ */ 9 struct NODE *right; /* 右の子節点を指すポインタ */ 10 }; 11 float width; /* 幅 */ 12 void preorder(struct NODE *p, float v, float h); 13 struct NODE *mktree(); 14 15 int main() { 16 struct NODE *root; 17 18 /* 2 分探索木の作成 */ 19 root = mktree(); 20 21 /* 初期設定 */ 22 width = 1; 23 24 /* 前走査 */ 25 preorder(root->left,0,0); 26 printf("\n"); - 15 -

27 } 28 29 /* 前走査に従って 節点の x 座標 v,y 座標 hを出力する */ 30 void preorder(struct NODE *p, float v, float h) { 31 if( p == NULL ) { return; } 32 33 /* 座標 (v,-h) の出力 */ 34 printf("%8.5f,%8.5f\n",v,-h); 35 width = width/2; 36 preorder(p->left,v-width,h+1); 37 38 /* 座標 (v,-h) の出力 */ 39 printf("%8.5f,%8.5f\n",v,-h); 40 preorder(p->right,v+width,h+1); 41 width = width*2; 42 43 /* 座標 (v,-h) の出力 */ 44 printf("%8.5f,%8.5f\n",v,-h); 45 } 実行結果 % cc bt411.c 44 22 11 33 66 55 77 0 0.00000,-0.00000-0.50000,-1.00000-0.75000,-2.00000-0.75000,-2.00000-0.75000,-2.00000-0.50000,-1.00000-0.25000,-2.00000-0.25000,-2.00000-0.25000,-2.00000-0.50000,-1.00000 0.00000,-0.00000 0.50000,-1.00000 0.25000,-2.00000 0.25000,-2.00000 0.25000,-2.00000 0.50000,-1.00000 0.75000,-2.00000 0.75000,-2.00000 0.75000,-2.00000 0.50000,-1.00000 0.00000,-0.00000-16 -

2 分探索木の表示 1 節点の座標を csv ファイル ( 拡張子を csv とする ) にして保存する 2 Excel を起動し csv ファイルを読み込む 3 グラフ機能 ( 散布図 ) 使ってグラフを表示する 余分な座標軸等は削除する x 座標 y 座標 0 0-0.5-1 -0.75-2 -0.75-2 -0.75-2 -0.5-1 -0.25-2 -0.25-2 -0.25-2 -0.5-1 0 0 0.5-1 0.25-2 0.25-2 0.25-2 0.5-1 0.75-2 0.75-2 0.75-2 0.5-1 0 0 11 22 33 55 44 66 77-17 -