Microsoft PowerPoint - kougi10.ppt

Similar documents
Microsoft PowerPoint - kougi9.ppt

Microsoft PowerPoint - kougi11.ppt

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

memo

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

Microsoft Word - no206.docx

第2回

Microsoft PowerPoint - 05.pptx

Microsoft Word - 13

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

Microsoft PowerPoint - kougi7.ppt

memo

Microsoft Word - 12

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

Microsoft PowerPoint - kougi8.ppt

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

PowerPoint プレゼンテーション

PowerPoint プレゼンテーション

二分木の実装

PG13-6S

Microsoft PowerPoint - kougi6.ppt

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

Microsoft PowerPoint - kougi4.ppt

Microsoft PowerPoint - 06.pptx

プログラミングI第10回

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

PowerPoint Template

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

alg2015-6r3.ppt

memo

Microsoft Word - NonGenTree.doc

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

PowerPoint Presentation

PowerPoint Presentation

Microsoft PowerPoint - kougi2.ppt

memo

Microsoft PowerPoint - lec10.ppt

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

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

Microsoft Word - no205.docx

アルゴリズムとデータ構造1

Microsoft PowerPoint - 7.pptx

ALG ppt

PowerPoint Presentation

( ) ( ) 30 ( ) 27 [1] p LIFO(last in first out, ) (push) (pup) 1

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

1. はじめに 二分木ヒープ 様々なアルゴリズムにおいて ある要素の集合またはリストから 最小 な要素を取り 出す必要がある そのような場合に使われる標準的データ構造が二分木ヒープ (binary heap) である あるオブジェクトO を考える そのオブジェクトは ラベル O. label と値

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

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

Microsoft Word - no12.doc

2. データ構造ヒープに保存するデータは 番号付けられて保存される 従って リスト L として保存することとする 3. アルゴリズム 3.1. 要素の追加新しい要素の追加は リストの終端に置くことで開始する つまり 最下層の一番右 または新たに最下層を生成してその一番左となる この後 この要素を正し

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

memo

r07.dvi

memo

ohp07.dvi

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

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

Prog1_12th

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

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

Microsoft PowerPoint - exp2-02_intro.ppt [互換モード]

PowerPoint プレゼンテーション

2006年10月5日(木)実施

自己紹介 ( 専門分野 ) プログラミング言語の研究 特に基礎理論 研究の出発点 : 自分がうまくプログラムが書けないのを言語のせいにする プログラムの間違いを自動発見する仕組みを作る そもそも間違いを犯しにくいプログラミング言語を作る

Microsoft Word - no15.docx

PowerPoint Presentation

Microsoft PowerPoint - C言語の復習(配布用).ppt [互換モード]

プログラミング基礎

第12回:木構造

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

コマンドラインから受け取った文字列の大文字と小文字を変換するプログラムを作成せよ 入力は 1 バイトの表示文字とし アルファベット文字以外は変換しない 1. #include <stdio.h> 2. #include <ctype.h> /*troupper,islower,isupper,tol

Microsoft PowerPoint Java基本技術PrintOut.ppt [互換モード]

関数の呼び出し ( 選択ソート ) 選択ソートのプログラム (findminvalue, findandreplace ができているとする ) #include <stdiu.h> #define InFile "data.txt" #define OutFile "surted.txt" #def

関数の呼び出し ( 選択ソート ) 選択ソートのプログラム (findminvalue, findandreplace ができているとする ) #include <stdio.h> #define InFile "data.txt" #define OutFile "sorted.txt" #def

program7app.ppt

A/B (2018/10/19) Ver kurino/2018/soft/soft.html A/B

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

問 2 ( 型変換 ) 次のプログラムを実行しても正しい結果が得られない 何が間違いかを指摘し 正しく修正せよ ただし int サイズが 2 バイト long サイズが 4 バイトの処理系での演算を仮定する #include <stdio.h> int main( void ) { int a =

(2) 構造体変数の宣言 文法は次のとおり. struct 構造体タグ名構造体変数名 ; (1) と (2) は同時に行える. struct 構造体タグ名 { データ型変数 1; データ型変数 2;... 構造体変数名 ; 例 : struct STUDENT{ stdata; int id; do

グラフの探索 JAVA での実装

Microsoft PowerPoint - 6.pptx

DA13

プログラミング基礎

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

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

演習課題No12

平成 31 年度 筑波大学大学院博士課程 システム情報工学研究科 コンピュータサイエンス専攻 博士前期課程 ( 一般入学試験 8 月期 ) 試験問題基礎科目 ( 数学, 情報基礎 ) Mathematics/Fundamentals of Computer Science [ 注意事項 ][Inst

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

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

(search: ) [1] ( ) 2 (linear search) (sequential search) 1

untitled

Functional Programming

Microsoft Word - NonGenList.doc

プログラミング及び演習 第1回 講義概容・実行制御

DF-200

Microsoft PowerPoint - lecture02.pptx

O(N) ( ) log 2 N

JavaプログラミングⅠ

Prog1_10th

Transcription:

C プログラミング演習 第 10 回二分探索木 1

例題 1. リストの併合 2 つのリストを併合するプログラムを動かしてみる head1 tail1 head2 tail2 NULL NULL head1 tail1 tail1 があると, リストの併合に便利 NULL 2

#include "stdafx.h" #include <math.h> struct data_list { int data; struct data_list *next; ; void print_list(struct data_list *p) { struct data_list *x; if ( p == NULL ) { return; printf( "%d", p->data ); x = p->next; while( x!= NULL ) { printf( ", %d", x->data ); x = x-> next; printf( " n" ); struct data_list *new_list(int x) { struct data_list *c = new(struct data_list); c->data x; c->next = NULL; return c; void insert_list(struct data_list *p, int x) { struct data_list *c = new(struct data_list); c->data p->data; c->next p->next; p->data x; p->next = c; int _tmain(int argc, _TCHAR* argv[]) { int ch; struct data_list *head1; struct data_list *tail1; struct data_list *head2; struct data_list *tail2; head1 = new_list( 6789 ); insert_list( head1, 45 ); tail1 = head1->next; // 2 個目の要素を作った時点で head1->next と tail1 が等しい insert_list( head1, 123 ); head2 = new_list( 789 ); insert_list( head2, 56 ); tail2 = head2->next; // 2 個目の要素を作った時点で head2->next と tail2 が等しい insert_list( head2, 1234 ); printf( " 併合前 n" ); print_list( head1 ); print_list( head2 ); // tail1->next = head2; tail1 = tail2; printf( " 併合後 n" ); print_list( head1 ); printf( "Enter キーを 1,2 回押してください. プログラムを終了します n"); ch getchar(); ch = getchar(); return 0; tail1->next = head2; tail1 = tail2; 3

実行結果の例 4

二分探索木 (binary search tree) 整列可能な任意個数のデータ集合に対し 効率良い探索 ( 二分探索 ) を行うためのデータ構造整列前 :35 46 21 13 61 40 69 整列後 ( 昇順 ):13 21 35 40 46 61 69 節点から出る枝が高々 2 本の木構造 ( 二分木 ) を作り 各節点にデータを置く 5

二分探索木の構造 節点 (node) と枝 (branch) 枝はデータ間の ( 親子 ) 関係を表す 節点に入る ( 親からの ) 枝は 1 本 節点から出ていく ( 子への ) 枝は 0 または 1 または 2 本 親 親 節点 (node) 枝 (branch) 子 子 子 6

二分探索木の構造 ( つづき ) 根 (root): 親を持たない節点 葉 (leaf): 子を持たない節点 部分木 (subtree): 任意の節点から下のすべての枝と節点 根 (root) 部分木 (subtree) 葉 (leaf) 7

二分探索木の再帰的構造 左部分木 右部分木も二分木をなす 親節点に対する処理が 子節点に対する処理に帰着されることが多い ( 例 ) 探索において, 子へ移動し, 親での処理と同様の処理を繰り返す 再帰関数を用いて自然に表現できる 左部分木 右部分木 左部分木 右部分木 8

二分探索木の各ノードを C 言語の構造体で表現 left value left right value right left value 1 個の構造体 right // // 2 分木のノード struct BTNode { BTNode *left; BTNode *right; int int value; ; ; int value の部分は, 格納すべきデータに応じて変わる 9

二分探索木の節点 (node) の生成関数 new_node #include "stdafx.h" #include <math.h> struct BTNode { BTNode *left; BTNode *right; int value; ; struct BTNode *new_node(int x, struct BTNode *y, struct BTNode *z) { struct BTNode *w = new BTNode(); w->value = x; w->left = y; w->right = z; return w; int _tmain(int argc, _TCHAR* argv[]) { int ch; BTNode *root; root = new_node( 100, NULL, NULL ); メンバ value, left, right に値をセット 例題 2,3,4 で使用 printf( "Enter キーを 1,2 回押してください. プログラムを終了します n"); ch = getchar(); ch = getchar(); return 0; 10

例題 2. 二分探索木の生成 データの配置のしかた 左側のすべての子は親より小さく 右側のすべての子は親より大きく 35 21 46 13 40 61 69 new_node を 7 回呼び出して, 節点を 7 個作る 11

#include "stdafx.h" #include <math.h> struct BTNode { BTNode *left; BTNode *right; int value; ; void print_data( struct BTNode *root ) { if ( root->left!= NULL ) { print_data( root->left ); printf( "%d n", root->value ); if ( root->right!= NULL ) { print_data( root->right ); struct BTNode *new_node(int x, struct BTNode *y, struct BTNode *z) { struct BTNode *w = new BTNode(); w->value = x; w->left = y; w->right = z; return w; int _tmain(int argc, _TCHAR* argv[]) { int ch; BTNode *root; root = new_node( 35, new_node( 21, new_node(13, NULL, NULL), NULL), new_node( 46, new_node(40, NULL, NULL), new_node(61, NULL, new_node(69, NULL, NULL)))); print_data( root ); printf( "Enter キーを 1,2 回押してください. プログラムを終了します n"); ch = getchar(); ch = getchar(); return 0; in-order で要素を表示 (in-order については後述 ) 2 分木の生成 12

実行結果の例 13

in-order での表示 void print_data( struct BTNode *root ) { if ( root->left!= NULL ) { print_data( root->left ); printf( "%d n", root->value ); if ( root->right!= NULL ) { print_data( root->right ); 35 最初に左部分木次に自分 ( 節点 ) 最後に右部分木 21 46 13 40 61 69 14

例題 3. 二分探索木における探索 指定された要素が存在するかを探す 40 有り 41 無し 35 21 46 13 40 61 69 15

二分探索木における探索 根 (root) から始める 探索キーの値と, 各節点のデータを比較し目標となるデータを探す 探索キーよりも節点のデータが小さいときは, 右側の子に進む 探索キーよりも節点のデータが大きいときは, 左側の子に進む 16

探索の例 ( 例 ) 節点 40を探す場合 1. 根の値 (35) と, 探索キー (40) を比較 2. 探索キーの方が大きいので, 右側の子節点へ移る 3. 次に移った節点の値 (46) と探索キー (40) を比較し 4. 探索キーの方が小さいので, 左の子節点へ移る 5. 次に移った節点 (40) が, 目標の節点である 35 21 46 13 40 61 69 17

#include "stdafx.h" #include <math.h> struct BTNode { BTNode *left; BTNode *right; int value; ; struct BTNode *find_node(int x, struct BTNode *root) { BTNode *node; node = root; while( ( node!= NULL ) && ( x!= node->value ) ) { if ( x < node-> value ) { node = node->left; else { node = node->right; return node; struct BTNode *new_node(int x, struct BTNode *y, struct BTNode *z) { struct BTNode *w = new BTNode(); w->value = x; w->left y; w->right = z; return w; int _tmain(int argc, _TCHAR* argv[]) { int ch; BTNode *root; BTNode *y; root = new_node( 35, new_node( 21, new_node(13, NULL, NULL), NULL), new_node( 46, new_node(40, NULL, NULL), new_node(61, NULL, new_node(69, NULL, NULL)))); y = find_node( 40, root ); if ( y == NULL ) { printf( "40 は無し n" ); else { printf( "40 は有り n" ); printf( "Enter キーを 1,2 回押してください. プログラムを終了します n"); ch getchar(); ch = getchar(); return 0; 探索 ( 見つからなければ NULL を返す ) 2 分木の生成 18

探索を行う関数 struct BTNode *find_node(int x, struct BTNode *root) { BTNode *node; node = root; while( ( node!= NULL ) && ( x!= node->value ) ) { if ( x < node-> value ) { node = node->left; else { node = node->right; return node; 19

実行結果の例 20

例題 4. 二分探索木への挿入 要素の挿入を行う関数を作る 35 46 21 13 61 40 69 を挿入すると, 例題 1と同じ二分探索木ができる 35 21 46 13 40 61 69 21

二分探索木への挿入 二分探索木に新たなデータを挿入する 挿入すべき位置を探す (find_node と同じ要領 ) 新たな節点を生成 挿入位置として見つかった節点において 新たな節点をポイントするようにポインタを書き換える 22

#include "stdafx.h" #include <math.h> struct BTNode { BTNode *left; BTNode *right; int value; ; void print_data( struct BTNode *root ) { if ( root->left!= NULL ) { print_data( root->left ); printf( "%d n", root->value ); if ( root->right!= NULL ) { print_data( root->right ); struct BTNode *new_node(int x, struct BTNode *y, struct BTNode *z) { struct BTNode *w = new BTNode(); w->value = x; w->left = y; w->right = z; return w; struct BTNode *insert_node(struct BTNode *node, int x) { if ( node == NULL ) { return new_node(x, NULL, NULL); else if ( x < node->value ) { node->left = insert_node(node->left, x); return node; else if ( x > node->value ) { node->right = insert_node(node->right, x); return node; else { return node; int _tmain(int argc, _TCHAR* argv[]) { int ch; BTNode *root; root = new_node( 35, NULL, NULL ); insert_node( root, 46 ); insert_node( root, 21 ); insert_node( root, 13 ); insert_node( root, 61 ); insert_node( root, 40 ); insert_node( root, 69 ); print_data( root ); printf( "Enter キーを 1,2 回押してください. プログラムを終了します n"); ch getchar(); ch = getchar(); return 0; 最初は, 節点を 1 個含む二分探索木を作り, その後, 残りの要素を挿入する 23

挿入を行う関数 struct BTNode *insert_node(struct BTNode *node, int x) { if ( node == NULL ) { return new_node(x, NULL, NULL); else if ( x < node->value ) { node->left = insert_node(node->left, x); return node; else if ( x > node->value ) { node->right = insert_node(node->right, x); return node; else { return node; 24

実行結果の例 25

木の踏査 (tree traversal) 一定の手順で木の各節点を訪れ 処理を行う 3 とおりの手順 pre-order traversal ( 行きがけ順 ) post-order traversal ( 帰りがけ順 ) in-order traversal ( 通りがけ順 ) 処理の内容によって使い分ける 26

通りがけ順 (in-order traversal) 1. 左の子節点以下を処理 ( 左部分木を辿る ) 2. 親節点について処理 ( 根を辿る ) 3. 右の子節点以下を処理 ( 右部分木を辿る ) A 2 根を辿る B C D E F G D, B, E, A, F, C, G の順に処理を行う 1 左部分木を辿る 3 右部分木を辿る 27

帰りがけ順 (post-order traversal) 1. 左の子節点以下を処理 2. 右の子節点以下を処理 3. 親節点について処理 A B C D E F G D, E, B, F, G, C, A の順に処理を行う 28

通りがけ順 (in-order traversal) 1. 左の子節点以下を処理 2. 親節点について処理 3. 右の子節点以下を処理 A B C D E F G D, B, E, A, F, C, G の順に処理を行う 29