解説
再帰関数とスタック操作のトレース問題です。スタックは後入れ先出し(LIFO)なので、[1, 2, 3] の表記では右端の3が最初に pop されます。関数 f( ) は「A が空でなければ、A から pop した値を C に push → f( ) を再帰呼出し → C から pop した値を B に push」を行います。トレースすると、1回目の呼出しで A から3を pop して C へ(C=[1,2,3,3])、2回目で2を C へ(C=[1,2,3,3,2])、3回目で1を C へ(C=[1,2,3,3,2,1])、4回目は A が空なので何もせず戻ります。ここから再帰が巻き戻り、3回目の呼出しの続きで C から1を pop して B へ(B=[1,2,3,1])、2回目の続きで2を B へ(B=[1,2,3,1,2])、1回目の続きで3を B へ(B=[1,2,3,1,2,3])。結果、B は [1, 2, 3, 1, 2, 3] となりアが正解です。A の値が C で一度逆順になり、B へ移すときに再び逆順に戻って元の順序で積まれる、という二重反転の構造がポイントです。
なぜ他の選択肢は違うのか
- 選択肢 イ
- [1, 2, 3, 3, 2, 1] は、C に積まれた直後の並び(3, 2, 1 の順で push された状態)がそのまま B に移ると考えた場合の誤りです。実際には B への push は再帰の巻き戻り時に行われ、C の上から 1→2→3 の順で pop されて B に積まれるため、もう一度順序が反転して元の 1, 2, 3 の順になります。「スタック経由の移し替えは1回ごとに逆順になる」ことを意識し、2回の移し替えで順序が戻る点を見落とさないようにしましょう。
- 選択肢 ウ
- [3, 2, 1, 1, 2, 3] は、B の初期値 [1, 2, 3] が何らかの理由で逆順の [3, 2, 1] になったと誤解した場合の値です。関数 f( ) は B に対して push しか行わず、B の既存要素の順序が変わることはありません。初期値部分はそのまま保たれ、新しい値はその上(右側)に積まれていきます。スタック表記の左端が底、右端が頂上であることを確認してからトレースを始めると混乱を防げます。
- 選択肢 エ
- [3, 2, 1, 3, 2, 1] は、B の初期値が逆転し、かつ追加分も C の積み順のまま移ると考えた、二重の誤解による値です。実際には初期値 [1, 2, 3] は不変で、追加されるのも再帰の巻き戻りによって 1, 2, 3 の順です。再帰関数のトレースでは「呼出し時の処理」と「戻ってからの処理」を分けて書き出し、各時点のスタックの中身を表にして追うのが確実です。