━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 課題1 (2分木のデータ構造) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
●準備 次のファイルを,ディレクトリ ~/AdvProg/T6/ に保存しておく. tree.h 2分木のデータと基本関数のためのヘッダ tree.c 2分木の基本関数 ex1.c 課題1解答用ひな型 Makefile 自動コンパイル用 予習時に上記のソースファイルと以下の課題を熟読し,疑問点を明らかにしておく. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ●課題一覧 基本課題 1a 2分木データの生成と表示 1b 2分木を扱う再帰関数の作成 1c 2分木のデータ構造の理解 発展課題 1d 2分木に関する判定 1e 2分木の加工 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ●基本課題 1a (2分木データの生成と表示) 2分木の節を格納するためのデータ構造 (Tree 型) が,2分木のデータと基本関数の ヘッダファイル tree.h で,次のように定義されている. typedef struct _tree { char node; /* 節のデータ (1文字) */ struct _tree *left; /* 左の子へのポインタ */ struct _tree *right; /* 右の子へのポインタ */ } Tree;2分木の枝と葉のデータを生成するための二つの関数 branch() と leaf() を作れ. 2分木の基本関数のプログラムファイル tree.c にある定義を,以下の説明に沿って 完成させること. Tree *branch(char x, Tree *l, Tree *r); ・節 (Tree 型の構造体) を格納する記憶領域を確保 ・節を初期化 (節データを x,左右の子へのポインタを l, r に設定) ・生成した Tree 型の構造体へのポインタを戻り値として返却
Tree *leaf(char x); ・節 (Tree 型の構造体) を格納する記憶領域を確保 ・節を初期化 (節データを x,左右の子へのポインタを NULL に設定) ・生成した Tree 型の構造体へのポインタを戻り値として返却
これ以降の課題の答えは,課題1のソースファイル ex1.c に書き込む. 関数 branch() と leaf() を使って,算術式を表す2分木のデータを生成し, 各2分木の根へのポインタを,Tree * 型の変数に格納せよ. 例えば,算術式 0 a + b (x + (y + 1)) * z を表すデータを作るなら,それぞれ,次の図の2分木を生成する.
![]()
![]()
ファイル tree.c で定義された関数 show_tree() の処理内容を理解した上で, この関数を使って2分木を表示し,意図通りのデータができていることを確かめよ. 補足 ●基本課題 1b (2分木を扱う再帰関数の作成) 2分木の高さを求める関数 height() を作れ. ここでの木の高さは,根から葉へたどるときに通る頂点数の最大値,と定義する. 例えば,課題 1a の三つの2分木の高さは,それぞれ 1, 2, 4 である. 十分な数の検査データを作り,動作の正しさを確かめよ. 補足 ●基本課題 1c (2分木のデータ構造の理解) まず,次の2分木のデータを生成するプログラムを作る.
Tree *t1, *t2, *t3; t1 = leaf('a'); t2 = branch('+', leaf('1'), leaf('b')); t3 = branch('*', t1, t2); 2分木の節の内容を詳細表示する関数 show_node() を使って, t1, t2, t3 が指す節が記憶領域上でどのように格納されるかを調べよ. また,Tree 型 (つまり struct _tree 型) と,その構成要素である char 型,Tree * 型,それぞれの型のデータの記憶に必要なバイト数を, sizeof(Tree), sizeof(char), sizeof(Tree *),の値を表示して調べよ. この実行結果をもとに (必要なら他の追加実験をして), 2分木全体が記憶領域上でどのように格納されるかを説明 (図解) せよ. 補足 ────────────────────────────────────── ●発展課題 1d (2分木に関する判定) 与えられた2分木が左右対称かどうかを判定する関数 is_symmetric() を作れ. 例えば,算術式 x や (y + 1) * (1 + y) を表す木
![]()
は対称的だが,a * 1 や (a * 1) + (1 + a) を表す木
![]()
は対称的ではない. 補足 ●発展課題 1e (2分木の加工) 2分木を左右反転した鏡像を求める関数 mirror() を作れ. 例えば,(a * b) * (1 + x) の2分木に対して (x + 1) * (b * a) の2分木 が得られればよい (下図).
→
補足 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 演習のホームページ 山田 俊行 https://www.cs.info.mie-u.ac.jp/~toshi/