基本情報技術者 2014年 春期 午前(科目A) 問06
問題文
2分木の各ノードがもつ記号を出力する再帰的なプログラムProc(n)の定義は、次のとおりである。このプログラムを、図の2分木の根(最上位のノード)に適用したときの出力はどれか。

選択肢
ア:+a*-bcd
イ:a+b-c*d
ウ:abc-d*+(正解)
エ:b-c*d+a
🔒 解説は解答すると表示されます
二分木の走査と演算子記号出力【午前解説】
正解の理由
正解は ウ です。Proc(n) の処理順は「左の子を全て処理 → 右の子を全て処理 → 自身を出力」という典型的な後順(post-order)です。図の木に対して後順を適用すると、まず左部分木(葉 a)が出力され「a」、次に右部分木に移ってその左部分木(b と c と - の順)で「b c -」を出力し、右の葉 d を出力してから「」を出力、最後に根の「+」を出力します。これをつなげると "a b c - d * +"、つまり連続した文字列では abc-d+ となり、選択肢のウと一致します。
解法ステップ
- Proc(n) の擬似コードを読み、出力の順序を確認する(左呼び出し → 右呼び出し → 出力)。
- それが後順(post-order)であると判断する。
- 木の根から開始し、再帰的に左部分木をすべてたどり出力を記録する(ここでは a)。
- 次に右部分木に移り、さらにその左部分木を先に処理して b, c, - の順で出力する。
- 右部分木の右葉 d を出力し、部分木の根 * を出力する。
- 最後に木全体の根 + を出力し、出力列を連結して abc-d*+ を得る。
選択肢別の誤答解説
- ア: +a*-bcd
- 説明: これは親を先に出力する前順(pre-order)に相当します。Proc の出力順は親を最後に出すため不適合です。
- イ: a+b-c*d
- 説明: これは中順(in-order)で、左→親→右の順で出力した場合に得られる表現です。Proc は親を最後に出すので異なります。
- ウ: abc-d*+
- 説明: 正解。後順(left, right, root)で処理した結果、葉から順に a → b → c → - → d → * → + となります。
- エ: b-c*d+a
- 説明: これは木構造のたどり方や出力順が混同された誤答です。特定の部分木だけ先に出す順序になっており、Proc の明示的な左→右→親の順序とは一致しません。
よくある誤解
- 「左→親→右(中順)」や「親→左→右(前順)」と混同すること。再帰呼び出しと出力位置を見れば区別できます。
- 図の左右を逆に読む(右を先に処理)してしまい順序が入れ替わる誤り。常に左を先にたどることを確認してください。
- 演算子を見て算術式の優先順位で並べ替える(中置表記を想像する)と、出力順の判定を誤ることがあります。
補足コラム
- 後順(post-order)巡回は式木(演算子ノードを内部、オペランドを葉に置く木)に対して後置記法(逆ポーランド記法、RPN)を生成します。得られた abc-d*+ をスタックで評価すれば式の値を求められます。
- 試験対策としては、ノードを読む順序をコードから確実に引き出す練習を繰り返すことが重要です。「再帰呼出の順番」と「出力するタイミング(呼ぶ前か後か)」をチェックしましょう。
FAQ
Q: 「Proc(n) が出力を呼び出しの前にしていたらどうなる?」
A: その場合は親を先に出力する前順(pre-order)になり、出力列は + a * - b c d のようになります(アの形式)。
A: その場合は親を先に出力する前順(pre-order)になり、出力列は + a * - b c d のようになります(アの形式)。
Q: 「中順(in-order)はどんなときに使う?」
A: 中置表記(通常の数学表現)を得たいときに使いますが、二分演算子木でのみ意味がわかりやすく、左→親→右で出力します(図ではイ)。
A: 中置表記(通常の数学表現)を得たいときに使いますが、二分演算子木でのみ意味がわかりやすく、左→親→右で出力します(図ではイ)。
Q: 「後順が実務で使われる場面は?」
A: 式の評価(逆ポーランド記法)や、子リソースを削除して最後に親を削除するような後処理が必要なアルゴリズムで使います。
A: 式の評価(逆ポーランド記法)や、子リソースを削除して最後に親を削除するような後処理が必要なアルゴリズムで使います。
関連キーワード: 二分木、後順巡回、ポストオーダー、再帰、逆ポーランド記法、式木、木構造、深さ優先探索、演算子ノード、葉ノード

\ せっかくなら /
基本情報技術者を
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

