基本情報技術者試験 科目Bの練習問題20問。線形探索・二分探索・ソート・データ構造・再帰の5つの型を4問ずつ、擬似言語のコード・選択肢・正答・トレース表つきで解きます。各章の下に、同じ論点の科目A・旧午前の過去問も置きました。
目次
結論:基本情報の科目Bの練習は、線形探索・二分探索・ソート・データ構造・再帰の5つの型を、変数の表(トレース表)を書きながら4問ずつ解くのが近道です。この記事の20問は合格ナビが作った問題で、正答とトレース表がついています。
出題数・合格基準・擬似言語の読み方・IPAの公開問題の使い方は、科目Bの対策にまとめています。
基本情報の科目B練習問題はどう解く?5つの型を4問ずつトレースする
科目Bの練習問題は、型ごとに変数の表を書き、1行ずつ追えば解けます。トレース表は、プログラムの動きを1コマずつ撮った連続写真のようなものです。頭の中だけで追わず、紙に1コマずつ残します。
| 型 | 問題数 | 何を追うか | 表の書き方 |
|---|---|---|---|
| 1. 線形探索・集計 | 4問 | 合計・最大値・個数 | i と集計の変数の2列 |
| 2. 二分探索 | 4問 | lo・hi・mid | 3つの変数を縦に並べる |
| 3. ソート | 4問 | バブル・選択・挿入 | 1パスごとの配列を縦に並べる |
| 4. データ構造 | 4問 | スタック・キュー・リスト | スタックは縦積み、キューは横の列 |
| 5. 再帰・木 | 4問 | 階乗・フィボナッチ・木の深さ | 呼び出しを縦に積み、帰りに計算する |
解く順番は、型1から型4までを先に、型5を最後にします。型1のループの追い方が、ほかの4つの型の土台になるからです。
コードは、IPAの擬似言語の記述形式(別紙2)に沿って書きました。連結リストのノードの書き方だけは、説明のために補ったものです。問題はすべてオリジナルで、本番の問題の転載ではありません。
各章の下の過去問は、合格ナビの基本情報の問題データ(科目Aのサンプル問題・公開問題120問と旧午前400問の計520問・2026-10-30集計)から、同じ論点のものを選びました。型ごとの解き方のコツは科目B(アルゴリズム・プログラミング)攻略法にあります。
パターン1:線形探索・集計系(4問)
線形探索・集計の問題は、i と集計の変数の2列の表を書けば解けます。配列を先頭から末尾まで1つずつ見て、合計・最大値・個数などを数えます。
問題1-1:配列の合計値
擬似言語コード
```
整数型の配列: a ← {3, 7, 2, 8, 5}
整数型: i, goukei
goukei ← 0
for (i を 1 から 5 まで 1 ずつ増やす)
goukei ← goukei + a[i]
endfor
```
次のコードを実行したとき、goukei の値はいくつになるか。
選択肢:
- ア 20
- イ 23
- ウ 25
- エ 28
正答: ウ(25)
ハンドトレース表:
| i | a[i] | goukei |
|---|---|---|
| 初期 | — | 0 |
| 1 | 3 | 3 |
| 2 | 7 | 10 |
| 3 | 2 | 12 |
| 4 | 8 | 20 |
| 5 | 5 | 25 |
解法のポイント: goukei を0で初期化し、ループで a[i] を加算し続けるだけです。配列が1始まりか0始まりかに注意(この問題は1始まり)。
問題1-2:最大値の検出
擬似言語コード
```
整数型の配列: a ← {4, 9, 2, 6, 1, 8}
整数型: i, maxVal
maxVal ← a[1]
for (i を 2 から 6 まで 1 ずつ増やす)
if (a[i] > maxVal)
maxVal ← a[i]
endif
endfor
```
次のコードを実行したとき、maxVal の値はいくつになるか。
選択肢:
- ア 6
- イ 8
- ウ 9
- エ 10
正答: ウ(9)
ハンドトレース表:
| i | a[i] | a[i] > maxVal? | maxVal |
|---|---|---|---|
| 初期 | — | — | 4(a[1]) |
| 2 | 9 | 9 > 4 → TRUE | 9 |
| 3 | 2 | 2 > 9 → FALSE | 9 |
| 4 | 6 | 6 > 9 → FALSE | 9 |
| 5 | 1 | 1 > 9 → FALSE | 9 |
| 6 | 8 | 8 > 9 → FALSE | 9 |
解法のポイント: 最大値検出は「最初の要素でmaxValを初期化→ループはi=2から」というパターンが固定。ループをi=1から始めると自分自身との比較が1回入るが結果は同じ。初期値の取り方を間違えないこと。
問題1-3:条件を満たす要素の個数
擬似言語コード
```
整数型の配列: scores ← {72, 58, 85, 91, 63, 78, 45, 88}
整数型: i, count
count ← 0
for (i を 1 から 8 まで 1 ずつ増やす)
if (scores[i] ≧ 70)
count ← count + 1
endif
endfor
```
次のコードを実行したとき、count の値はいくつになるか。
選択肢:
- ア 3
- イ 4
- ウ 5
- エ 6
正答: ウ(5)
ハンドトレース表:
| i | scores[i] | >= 70? | count |
|---|---|---|---|
| 初期 | — | — | 0 |
| 1 | 72 | TRUE | 1 |
| 2 | 58 | FALSE | 1 |
| 3 | 85 | TRUE | 2 |
| 4 | 91 | TRUE | 3 |
| 5 | 63 | FALSE | 3 |
| 6 | 78 | TRUE | 4 |
| 7 | 45 | FALSE | 4 |
| 8 | 88 | TRUE | 5 |
解法のポイント: 70以上(≥70)を満たす要素は72・85・91・78・88の5個。「>70(70より大きい)」と「>=70(70以上)」では、ちょうど70の要素があると答えが変わるため、境界値(= が含まれるかどうか)を必ず確認してください。
問題1-4:平均値と閾値比較
擬似言語コード
```
整数型の配列: a ← {10, 20, 30, 40, 50}
整数型: i, goukei, heikin
goukei ← 0
for (i を 1 から 5 まで 1 ずつ増やす)
goukei ← goukei + a[i]
endfor
heikin ← goukei ÷ 5 の商
```
次のコードを実行したとき、heikin の値はいくつになるか。ただし整数の割り算は小数点以下を切り捨てる。
選択肢:
- ア 28
- イ 30
- ウ 32
- エ 35
正答: イ(30)
ハンドトレース表:
| ステップ | 計算 | 結果 |
|---|---|---|
| goukei初期化 | 0 | 0 |
| +a[1] | 0+10 | 10 |
| +a[2] | 10+20 | 30 |
| +a[3] | 30+30 | 60 |
| +a[4] | 60+40 | 100 |
| +a[5] | 100+50 | 150 |
| heikin | 150/5 | 30 |
解法のポイント: 合計を求めてから、要素の数で割る2段階の計算です。整数の割り算の切り捨てに注意します(この問題は割り切れるので影響なし)。割る数を、配列の要素の数と合わせることが大切です。
同じ論点の過去問(配列とループ)
- 配列の単語を一つずつ後ろへずらす流れ図(平成23年度 秋期 問7)
- 流れ図の実行順から初期値の関係を求める(令和5年度 科目A 問11)
- 10進整数を2進数に変換する流れ図(科目A サンプル問題 問2)
- 2次元配列の要素を別の配列へ移す流れ図(科目A サンプル問題 問6)
パターン2:二分探索(4問)
二分探索の問題は、lo・hi・mid の3つの変数を縦に並べて追えば解けます。辞書を真ん中で開き、探す言葉が前か後ろかを決めて半分を捨てるのと同じ動きです。並べ替え済みの配列で、真ん中の値と比べて探す範囲を半分ずつにします。
問題2-1:基本的な二分探索
擬似言語コード
```
整数型の配列: a ← {2, 5, 8, 12, 16, 23, 38, 56, 72, 91}
整数型: lo, hi, mid, target
target ← 23
lo ← 1
hi ← 10
while (lo ≦ hi)
mid ← (lo + hi) ÷ 2 の商 / 整数除算(切り捨て) /
if (a[mid] = target)
lo ← hi + 1 / 探索終了(ループを抜ける) /
elseif (a[mid] < target)
lo ← mid + 1
else
hi ← mid - 1
endif
endwhile
```
ループが終了したとき、最後に mid が指していたインデックスはいくつか。
選択肢:
- ア 4
- イ 5
- ウ 6
- エ 7
正答: ウ(6)
ハンドトレース表:
| 反復 | lo | hi | mid | a[mid] | 比較結果 |
|---|---|---|---|---|---|
| 1 | 1 | 10 | 5 | 16 | 16 < 23 → lo←6 |
| 2 | 6 | 10 | 8 | 56 | 56 > 23 → hi←7 |
| 3 | 6 | 7 | 6 | 23 | 23 = 23 → 探索終了 |
解法のポイント: target=23はインデックス6の要素(1始まり)。3回の反復で発見。mid の計算は (lo+hi)/2 の整数部のみ取ることに注意。ループ終了条件「lo > hi」または「発見時の強制終了」の両方を把握してください。
問題2-2:探索失敗時の動作
擬似言語コード(問題2-1と同じ配列・同じロジック)
```
target ← 15
lo ← 1
hi ← 10
while (lo ≦ hi)
mid ← (lo + hi) ÷ 2 の商
if (a[mid] = target)
lo ← hi + 1
elseif (a[mid] < target)
lo ← mid + 1
else
hi ← mid - 1
endif
endwhile
```
target=15 は配列に存在しない。ループが終了したとき、lo と hi の値の組み合わせとして正しいものはどれか。
選択肢:
- ア lo=4, hi=4
- イ lo=5, hi=4
- ウ lo=4, hi=3
- エ lo=5, hi=3
正答: イ(lo=5, hi=4)
ハンドトレース表:
| 反復 | lo | hi | mid | a[mid] | 比較(target=15) |
|---|---|---|---|---|---|
| 1 | 1 | 10 | 5 | 16 | 16 > 15 → hi←4 |
| 2 | 1 | 4 | 2 | 5 | 5 < 15 → lo←3 |
| 3 | 3 | 4 | 3 | 8 | 8 < 15 → lo←4 |
| 4 | 4 | 4 | 4 | 12 | 12 < 15 → lo←5 |
| 5 | 5 | 4 | — | lo > hi → ループ終了 |
解法のポイント: 探索失敗時は lo > hi になってループを抜けます。最後の反復でloが5になり、hiが4のままでlo > hiが成立してループ終了。「失敗時の状態」も追えるようにしておきましょう。
問題2-3:二分探索の繰り返し回数
配列要素数Nに対して二分探索の最大繰り返し回数を求める問題です(コードなし・論理問題)。
要素数 N = 1,000 のソート済み配列に対して二分探索を行う場合、最大で何回の比較(mid の計算・比較)が必要か。ただし log₂(1000) ≈ 9.96 とする。
選択肢:
- ア 10回
- イ 11回
- ウ 1000回
- エ 500回
正答: ア(10回)
解説: 二分探索の最大の比較回数は、log₂N の整数部分に1を足した回数です。N=1000 なら log₂(1000) ≈ 9.96 の整数部分9に1を足して、10回になります。
線形探索は最大1,000回なので、比べる回数が大きく減ります。計算量で書くと、線形探索は O(N)、二分探索は O(log N) です。
解法のポイント: 1回比べるごとに、残りの範囲はおよそ半分になります。2⁹=512 ≦ 1000 < 1024=2¹⁰ なので、10回比べれば必ず1つに絞れます。「2を何回掛けると N を超えるか」と考えると暗算できます。
問題2-4:二分探索の変形(下限探索)
擬似言語コード
```
整数型の配列: a ← {3, 3, 5, 7, 7, 7, 9, 11}
整数型: lo, hi, mid, target, ans
target ← 7
lo ← 1
hi ← 8
ans ← -1
while (lo ≦ hi)
mid ← (lo + hi) ÷ 2 の商
if (a[mid] ≧ target)
ans ← mid
hi ← mid - 1
else
lo ← mid + 1
endif
endwhile
```
ループが終了したとき、ans の値はいくつか(target が最初に現れるインデックスを求めている)。
選択肢:
- ア 3
- イ 4
- ウ 5
- エ 6
正答: イ(4)
ハンドトレース表:
| 反復 | lo | hi | mid | a[mid] | >= 7? | ans | 操作 |
|---|---|---|---|---|---|---|---|
| 1 | 1 | 8 | 4 | 7 | YES | 4 | hi←3 |
| 2 | 1 | 3 | 2 | 3 | NO | 4 | lo←3 |
| 3 | 3 | 3 | 3 | 5 | NO | 4 | lo←4 |
| 終了 | 4 | 3 | — | lo > hi | — | 4 | — |
解法のポイント: ふつうの二分探索を変えて、「target 以上で、いちばん左の位置」を求める型です。a[mid] ≧ target のときに ans を記録し、さらに左を探します(hi ← mid - 1)。見つけても止まらない点が、問題2-1との違いです。
同じ論点の過去問(二分探索と2分探索木)
パターン3:ソートアルゴリズム(4問)
ソートの問題は、1パスごとの配列の状態を縦に並べて書けば解けます。バブルソート・選択ソート・挿入ソートの3つを押さえます。トランプの手札を、決まった手順で1回ずつ並べ直す様子を思い浮かべてください。
問題3-1:バブルソートのパス後状態
配列 [5, 3, 8, 1, 4] をバブルソート(隣接要素の比較・交換)で昇順に並び替えるとき、1パス目が終了した直後の配列の状態として正しいものはどれか。
ただしバブルソートの1パスとは「先頭から末尾に向かって隣接要素を比較し、前の要素が後の要素より大きければ交換する」操作を1回実施することとする。
選択肢:
- ア [1, 3, 5, 4, 8]
- イ [3, 5, 1, 4, 8]
- ウ [3, 1, 5, 4, 8]
- エ [1, 3, 4, 5, 8]
正答: イ([3, 5, 1, 4, 8])
ハンドトレース(1パス目):
| 比較位置 | 比較 | 交換? | 配列の状態 |
|---|---|---|---|
| 初期 | — | — | [5, 3, 8, 1, 4] |
| a[1]とa[2] | 5 > 3 | YES | [3, 5, 8, 1, 4] |
| a[2]とa[3] | 5 < 8 | NO | [3, 5, 8, 1, 4] |
| a[3]とa[4] | 8 > 1 | YES | [3, 5, 1, 8, 4] |
| a[4]とa[5] | 8 > 4 | YES | [3, 5, 1, 4, 8] → [3, 5, 1, 4, 8] |
解法のポイント: バブルソート1パス後は「最大値が末尾に確定」します(8が末尾へ)。先頭から順番に隣接交換を丁寧にトレースする。「パスN回後」「全体が完成するまでのパス数」を問う問題もあるため、各パス後の状態を縦に並べて書く習慣をつけてください。
問題3-2:選択ソートの動作
配列 [6, 2, 9, 1, 5] を選択ソート(昇順)で並び替えるとき、2パス目が終了した直後の配列の状態として正しいものはどれか。
ただし選択ソートの1パスとは「未ソート部分の最小値を探して先頭要素と交換する」操作とする。
選択肢:
- ア [1, 2, 5, 6, 9]
- イ [1, 2, 9, 6, 5]
- ウ [1, 2, 6, 5, 9]
- エ [1, 2, 6, 9, 5]
正答: イ([1, 2, 9, 6, 5])
ハンドトレース:
| パス | 未ソート部 | 最小値 | 交換位置 | 配列の状態 |
|---|---|---|---|---|
| 初期 | — | — | — | [6, 2, 9, 1, 5] |
| 1パス | [6,2,9,1,5] | 1(a[4]) | a[1]↔a[4] | [1, 2, 9, 6, 5] |
| 2パス | [2,9,6,5] | 2(a[2]) | 自身(交換なし) | [1, 2, 9, 6, 5] |
解法のポイント: 2パス後に先頭2要素が確定([1, 2, ...])。未ソート部 [9, 6, 5] はまだ乱れたまま。「最小値がすでに正位置にある場合は自身と交換(= 変化なし)」という場合があることも覚えておいてください。
問題3-3:挿入ソートの挿入位置
配列 [3, 7, 1, 8, 4] を挿入ソート(昇順)で並び替えるとき、3要素目(a[3]=1)を挿入した直後の配列の状態として正しいものはどれか。
ただし挿入ソートの各ステップとは「未ソート部の先頭要素を、ソート済み部の正しい位置に挿入する」操作とする。
選択肢:
- ア [1, 3, 7, 8, 4]
- イ [1, 3, 7, 4, 8]
- ウ [3, 1, 7, 8, 4]
- エ [1, 7, 3, 8, 4]
正答: ア([1, 3, 7, 8, 4])
ハンドトレース:
| ステップ | 操作 | 配列の状態 |
|---|---|---|
| 初期 | — | [3, 7, 1, 8, 4] |
| a[2]=7を挿入 | [3]にソート済み。7 > 3なのでそのまま | [3, 7, 1, 8, 4] |
| a[3]=1を挿入 | [3,7]にソート済み。1 < 7 → 7を右シフト。1 < 3 → 3を右シフト。先頭に1を挿入 | [1, 3, 7, 8, 4] |
解法のポイント: 挿入ソートは「ソート済み部を後ろから見て挿入位置を探す」動作です。1は3・7の両方より小さいため先頭(インデックス1)に挿入され、3と7が1つずつ右にシフトします。a[4]・a[5](8・4)はまだ未処理です。
問題3-4:ソートアルゴリズムの計算量比較
次の3つのソートアルゴリズムの最悪計算量(最も時間がかかるケース)を比較したとき、正しいものはどれか。
- バブルソート
- 選択ソート
- 挿入ソート(逆順配列の場合)
選択肢:
- ア 3つとも O(N) で同じ
- イ 3つとも O(N²) で同じ
- ウ バブルが最も速く、挿入が最も遅い
- エ 挿入が最も速く、選択が最も遅い
正答: イ(3つとも O(N²) で同じ)
解説: バブルソート・選択ソート・挿入ソートは、どれも最悪の計算量が O(N²) です。最悪の場合、N個の要素に N×(N-1)/2 回の比較が要る点が共通しています。挿入ソートは、ほぼ並んでいる配列なら比較が少なくて済みます。
計算量比較表(参考):
| アルゴリズム | 最良 | 平均 | 最悪 |
|---|---|---|---|
| バブルソート | O(N)(交換がなければ止める作りの場合) | O(N²) | O(N²) |
| 選択ソート | O(N²) | O(N²) | O(N²) |
| 挿入ソート | O(N) | O(N²) | O(N²) |
| クイックソート | O(N log N) | O(N log N) | O(N²) |
| マージソート | O(N log N) | O(N log N) | O(N log N) |
解法のポイント: 基本の3つは O(N²)、クイックソートの平均とマージソートは O(N log N) と分けて覚えます。
同じ論点の過去問(整列)
パターン4:データ構造操作系(4問)
データ構造の問題は、スタックは縦の積み上げ、キューは横の列として図にすれば解けます。スタックは積み重ねた皿で、上に置いた皿から取ります(後入れ先出し)。キューはレジの行列で、先に並んだ人から出ます(先入れ先出し)。
問題4-1:スタック操作の結果
スタックに対して次の操作を順番に実行したとき、最後にポップした値はいくつか。
操作順:push(5) → push(3) → push(8) → pop() → push(2) → pop()
選択肢:
- ア 2
- イ 3
- ウ 5
- エ 8
正答: ア(2)
スタック状態の追跡:
| 操作 | スタック状態(上が最新) | pop の戻り値 |
|---|---|---|
| 初期 | [] | — |
| push(5) | [5] | — |
| push(3) | [5, 3] | — |
| push(8) | [5, 3, 8] | — |
| pop() | [5, 3] | 8(取り出し) |
| push(2) | [5, 3, 2] | — |
| pop() | [5, 3] | 2(最後の取り出し) |
解法のポイント: スタックは「後入れ先出し(LIFO: Last In First Out)」。push(8)後にpop()で8が出て、その後push(2)→pop()で2が出ます。「最後にポップした値」を問われているので2が正答。スタックの状態を図の縦積みで追うと混乱が防げます。
問題4-2:キュー操作の結果
キューに対して次の操作を順番に実行したとき、2回目のdequeue() が返す値はいくつか。
操作順:enqueue(1) → enqueue(4) → enqueue(7) → dequeue() → enqueue(2) → dequeue()
選択肢:
- ア 1
- イ 2
- ウ 4
- エ 7
正答: ウ(4)
キュー状態の追跡(左が先頭・先に出る側):
| 操作 | キュー状態(左が先頭) | dequeue の戻り値 |
|---|---|---|
| 初期 | [] | — |
| enqueue(1) | [1] | — |
| enqueue(4) | [1, 4] | — |
| enqueue(7) | [1, 4, 7] | — |
| dequeue() | [4, 7] | 1(1回目) |
| enqueue(2) | [4, 7, 2] | — |
| dequeue() | [7, 2] | 4(2回目) |
解法のポイント: キューは「先入れ先出し(FIFO: First In First Out)」です。最初に入れた1が最初に出て、次に入れた4が2回目の dequeue で出ます。enqueue(2) はあとから入るので、4より後ろに並びます。
キューは横の列として書き、左(先頭)から取り出して追います。
問題4-3:スタックを使った数式評価(後置記法)
後置記法(逆ポーランド記法)の式 「3 4 + 2 * 5 -」 をスタックを使って評価したとき、最終結果はいくつか。
後置記法の評価規則:数値はスタックにプッシュ、演算子が来たらスタックから2つポップして演算し結果をプッシュ。
選択肢:
- ア 9
- イ 14
- ウ 7
- エ 19
正答: ア(9)
スタック状態の追跡:
| トークン | 操作 | スタック状態 |
|---|---|---|
| 3 | push(3) | [3] |
| 4 | push(4) | [3, 4] |
| + | pop→4, pop→3, push(3+4=7) | [7] |
| 2 | push(2) | [7, 2] |
| * | pop→2, pop→7, push(7×2=14) | [14] |
| 5 | push(5) | [14, 5] |
| - | pop→5, pop→14, push(14-5=9) | [9] |
解法のポイント: 後置記法はスタックで自然に評価できます。「演算子が来たら2つポップし、演算し、結果をプッシュ」という操作を繰り返すだけです。引き算・割り算は順序に注意します(先にポップした値が右側、あとからポップした値が左側。14 5 - なら 14-5)。
問題4-4:連結リストの操作
次の連結リスト操作の擬似言語コードを実行したとき、リストの最後の要素の値はいくつか。
初期状態:head → [5] → [3] → [7] → null
```
/ newNodeを値12で作成し、リストの末尾に追加する /
新ノード作成: newNode.val ← 12, newNode.next ← null
ノード型: current ← head
while (current.next ≠ null)
current ← current.next
endwhile
current.next ← newNode
```
選択肢:
- ア 5
- イ 7
- ウ 12
- エ null
正答: ウ(12)
トレース:
| ステップ | current | current.next |
|---|---|---|
| 初期 | head→[5] | [3] (≠null) |
| 反復1 | [3] | [7] (≠null) |
| 反復2 | [7] | null → ループ終了 |
| 末尾挿入 | [7].next ← newNode(12) | リスト:[5]→[3]→[7]→[12] |
解法のポイント: current.next が null になるまで進んで末尾を探し、末尾のノードの next に新しいノードをつなぎます。連結リストの「末尾に追加」の基本の形です。先頭への追加(head の付け替え)や、途中への挿入との違いも確かめておきましょう。
同じ論点の過去問(スタック・キュー・リスト)
- スタックに push と pop を行ったあとに残るデータ(平成21年度 秋期 問5)
- 2つのスタックで決まった順に出力する関数の順序(平成23年度 秋期 問5)
- 1つのスタックで出力できるデータ列(平成29年度 秋期 問5)
- 逆ポーランド表記法の式とスタックの深さ(平成25年度 春期 問6)
- 双方向リストに要素を追加したときのポインタ(令和5年度 科目A 問2)
- リストを配列で実現した場合の特徴(平成25年度 秋期 問6)
パターン5:再帰関数・木構造(4問)
再帰の問題は、呼び出しを縦に積んで書き、帰りに下から値を計算すれば解けます。5つの型の中で、表に書く量がいちばん多い型です。合わせ鏡のように同じ関数が中へ中へと呼ばれ、いちばん奥(基底ケース)で止まってから外へ戻ります。
問題5-1:再帰による階乗計算
擬似言語コード
```
○整数型: factorial(整数型: n)
if (n = 0)
return 1
else
return n * factorial(n - 1)
endif
```
`factorial(4)` を実行したとき、戻り値はいくつか。
選択肢:
- ア 4
- イ 10
- ウ 24
- エ 120
正答: ウ(24)
コールスタックのトレース:
| 呼び出し | n | 条件 | 展開 |
|---|---|---|---|
| factorial(4) | 4 | 4≠0 | return 4 × factorial(3) |
| factorial(3) | 3 | 3≠0 | return 3 × factorial(2) |
| factorial(2) | 2 | 2≠0 | return 2 × factorial(1) |
| factorial(1) | 1 | 1≠0 | return 1 × factorial(0) |
| factorial(0) | 0 | 0=0 | return 1 |
帰りがけ(戻り値の計算):
```
factorial(0) → 1
factorial(1) → 1 × 1 = 1
factorial(2) → 2 × 1 = 2
factorial(3) → 3 × 2 = 6
factorial(4) → 4 × 6 = 24
```
解法のポイント: 再帰は「行きがけ(呼び出し)」と「帰りがけ(戻り値の計算)」の2段階で追います。n=0が基底ケース(再帰の終了条件)。コールスタックを縦に書いて、帰りがけに下から掛け算を積み上げる手順で確実に解けます。
問題5-2:フィボナッチ数列
擬似言語コード
```
○整数型: fib(整数型: n)
if (n ≦ 1)
return n
else
return fib(n - 1) + fib(n - 2)
endif
```
`fib(6)` を実行したとき、戻り値はいくつか。
選択肢:
- ア 6
- イ 8
- ウ 11
- エ 13
正答: イ(8)
フィボナッチ数列の値(底から積み上げ):
| n | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|---|
| fib(n) | 0 | 1 | 1 | 2 | 3 | 5 | 8 |
解法のポイント: fib(n) = fib(n-1) + fib(n-2) で、fib(0)=0 と fib(1)=1 が基底ケースです。数列を0から順に積み上げると、fib(6)=8 と確かめられます。呼び出しをすべて書き出すと数が多くなるので、値を0から順に表で埋めるほうが速く解けます。
問題5-3:再帰による配列合計
擬似言語コード
```
整数型の配列: a ← {2, 4, 6, 8, 10}
○整数型: sum(整数型: i, 整数型: n)
if (i > n)
return 0
else
return a[i] + sum(i + 1, n)
endif
```
`sum(1, 5)` を実行したとき、戻り値はいくつか。
選択肢:
- ア 20
- イ 28
- ウ 30
- エ 32
正答: ウ(30)
コールスタックのトレース:
| 呼び出し | i | i > 5? | return |
|---|---|---|---|
| sum(1,5) | 1 | NO | a[1] + sum(2,5) = 2 + sum(2,5) |
| sum(2,5) | 2 | NO | 4 + sum(3,5) |
| sum(3,5) | 3 | NO | 6 + sum(4,5) |
| sum(4,5) | 4 | NO | 8 + sum(5,5) |
| sum(5,5) | 5 | NO | 10 + sum(6,5) |
| sum(6,5) | 6 | YES | return 0 |
帰りがけ: 10+0=10 → 8+10=18 → 6+18=24 → 4+24=28 → 2+28=30
解法のポイント: 再帰で配列合計を計算するパターン。終了条件「i > n → return 0」が重要。帰りがけに積み上げる値は a[1]+a[2]+...+a[5] = 2+4+6+8+10 = 30 です。
問題5-4:二分木の深さ(DFS)
擬似言語コード(二分木の最大深さを求める)
```
/ ノードは val(値)・left(左の子ノード)・right(右の子ノード)を持つ /
/ null はノードが存在しないことを示す /
○整数型: maxDepth(ノード型: node)
if (node = null)
return 0
else
整数型: leftDepth ← maxDepth(node.left)
整数型: rightDepth ← maxDepth(node.right)
return max(leftDepth, rightDepth) + 1
endif
```
以下の二分木で `maxDepth(root)` を実行したとき、戻り値はいくつか。
```
1
/ \
2 3
/ \
4 5
\
6
```
選択肢:
- ア 3
- イ 4
- ウ 5
- エ 6
正答: イ(4)
深さのトレース:
```
maxDepth(1)
├─ maxDepth(2)
│ ├─ maxDepth(4) → null,null → max(0,0)+1 = 1
│ └─ maxDepth(5)
│ ├─ maxDepth(null) → 0
│ └─ maxDepth(6) → null,null → max(0,0)+1 = 1
│ → max(0,1)+1 = 2
│ → max(1,2)+1 = 3
└─ maxDepth(3) → null,null → max(0,0)+1 = 1
→ max(3,1)+1 = 4
```
解法のポイント: 木の最大の深さは、左右の子の深さの大きいほうに1を足す再帰で求めます。いちばん長い道は 1→2→5→6 の4ノード分です。木の再帰は、葉(null)から戻る帰りの計算を順に追います。先に深い道を目で数えておくと、トレースの答えを確かめられます。
同じ論点の過去問(再帰と木)
- 再帰的に定義された関数 f(5) の値(科目A サンプル問題 問8)
- nの階乗を再帰的に計算する関数の式(平成28年度 春期 問7)
- 戻り番地を一時的に保存するのに適したデータ構造(平成21年度 春期 問5)
- 2分木の節に値を割り振る(平成28年度 春期 問5)
20問を表を書いて解き直し、5つの型を手で追えるようにしよう
科目Bの練習は、5つの型を4問ずつ、変数の表を書きながら解くのが近道です。答えが合っていても、表を書かずに当てた問題は、もう一度1行ずつ表を書いて解き直しましょう。
型ごとの過去問で同じ論点を確かめたら、科目Bの対策で紹介しているIPAのサンプル問題に進み、本番と同じ形式で時間を計って解いてみましょう。
よくある質問
Qこの記事の問題は、本番と同じ難しさですか?
本番の問題と難しさを比べたものではありません。この20問は、トレース表を書く手順を身につけるために合格ナビが作った問題です。手順に慣れたら、IPAが公開しているサンプル問題や公開問題で、時間を計って解く練習に進みます。
Qループの終わりを見落とさないコツはありますか?
while や for の行と、対応する endwhile・endfor の行を、読み始める前に鉛筆で囲みます。外枠を先に決めてから中の処理を追うと、どこで繰返しが終わるかを見落としにくくなります。while の条件(lo ≦ hi など)は、トレース表の列に1つ足して毎回書くと確実です。
Q再帰の問題を本番で解き切れないときは、どうすればよいですか?
解けない問題に時間を使い続けず、いったん飛ばして他の問題を先に解く方法があります。科目Bは全問に答える形式なので、最後に戻って、呼び出しを縦に積む表を書いて解き直します。
法令や試験の数字は、改正や年度で変わります。この記事の最終確認日は2026年10月30日です。申込みや合格基準は、必ず試験団体の公式情報で確かめてください。

