基本情報技術者試験 科目Bの「令和5年度 サンプル問題 問3」(while・クイックソート風の sort 手続)を、図解トレースで解説します。「最初に α 行に到達するときの data の状態」 だけを追えば良いので、while の判定を1列ずつ丁寧にトレースすると答えが出ます。
動画で見たい方はこちら▼
問題(令和5年度 サンプル問題 問3)
次の記述中の【 】に入れる正しい答えを、解答群の中から選べ。
ここで、配列の要素番号は 1 から始まる。
次の手続 sort は、大域の整数型の配列 data の、引数 first で与えられた要素番号から引数 last で与えられた要素番号までの要素を昇順に整列する。ここで、first < last とする。
手続 sort を sort(1, 5) として呼び出すと、/*** α ***/ の行を最初に実行したときの出力は「【 】」となる。
大域: 整数型の配列: data ← {2, 1, 3, 5, 4}
○ sort(整数型: first, 整数型: last)
整数型: pivot, i, j
pivot ← data[(first + last) ÷ 2 の商]
i ← first
j ← last
while (true)
while (data[i] < pivot)
i ← i + 1
endwhile
while (pivot < data[j])
j ← j − 1
endwhile
if (i ≥ j)
繰返し処理を終了する
endif
data[i] と data[j] の値を入れ替える
i ← i + 1
j ← j − 1
endwhile
data の全要素の値を要素番号の順に空白区切りで出力する /*** α ***/
if (first < i − 1)
sort(first, i − 1)
endif
if (j + 1 < last)
sort(j + 1, last)
endif
解答群
ア 1 2 3 4 5
イ 1 2 3 5 4
ウ 2 1 3 4 5
エ 2 1 3 5 4
解説
正解は エ「2 1 3 5 4」 です。
①トレース表を作成
data
| 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|
| 2 | 1 | 3 | 5 | 4 |
トレース表
| pivot | i | j | while(data[i] < 3) | while(3<data[j]) | if(i≧j) |
|---|---|---|---|---|---|
3 |
1 | 5 |
以下3行を反映済みです。
pivot ← data[(first + last) ÷ 2 の商]
i ← first
j ← last
②while (true)
条件判定は不要で、常に繰り返します。繰返し処理を終了する が実行されたときに終了します。
Memo: 大域変数はそのままトレースしてOK
冒頭の 大域(大域変数)は、関数をまたいで使える変数です。ここでは深く気にせず、そのままトレースして問題ありません。
③while (data[i] < pivot)
i を 1 ずつ増やしながら、data[i] < 3 が成り立つ限り進めます。
| pivot | i | j | while(data[i] < 3) | while(3<data[j]) | if(i≧j) |
|---|---|---|---|---|---|
| 3 | 5 | ||||
2 ○ |
|||||
| 3 | 1 ○ |
||||
3 × |
→ i = 3 で抜けます。
④while (pivot < data[j])
j を 1 ずつ減らしながら、3 < data[j] が成り立つ限り進めます。
| pivot | i | j | while(data[i] < 3) | while(3<data[j]) | if(i≧j) |
|---|---|---|---|---|---|
| 3 | 3 | 5 | |||
| 4 | 3< 4 ○ |
||||
| 3 | 3< 5 ○ |
||||
| 3< 3 × |
→ j = 3 で抜けます。
⑤if (i ≥ j)
| pivot | i | j | while(data[i] < 3) | while(3<data[j]) | if(i≧j) |
|---|---|---|---|---|---|
| 3 | 3 | 3 | |||
| 3≧3 ○ |
3 ≥ 3 で真なので、繰返し処理を終了する が実行されます。
⑥data の全要素の値を要素番号の順に空白区切りで出力する(α 行)
入れ替えは一度も発生していないので、data は初期状態のままです。
data
| 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|
| 2 | 1 | 3 | 5 | 4 |
なので、最初の出力は 「2 1 3 5 4」(エ)です。
Memo: 効率的なトレース
i は 1 から1ずつ増え、j は 5 から1ずつ減るので、data の配列表上で以下のように判定できます。
data
| 1 | 2 | 3 | 4 | 5 | |
|---|---|---|---|---|---|
| 2 | 1 | 3 | 5 | 4 | |
| data[i]<3 | ○ | ○ | × | ||
| 3<data[j] | × | ○ | ○ |
i, j が共に 3 になるとわかれば、あとは if (i ≥ j) を判定すれば OK です。
まとめ
while のネストは、 各 while の判定をトレース表に書いた上で進めると、ミスなくたどれます。
関連リンク

関連動画
while の基礎から学べる、同じ章の動画です。
講座の全動画はこちら(プレイリスト)。
