メインコンテンツへスキップ
基本情報技術者基本情報科目B擬似言語アルゴリズム

基本情報 科目B ソート(整列)のトレース練習|選択ソートで最小値を前へ運ぶ

科目Bの頻出アルゴリズム「ソート(整列)」を、二重ループの添字 i・j を表に書いて1行ずつ追うトレースで攻略。選択ソートで最小値を前へ運ぶ動きを具体例で実演し、min が位置を指すこと・tmp を使う交換・内側ループの開始位置のつまずきを解説します。

公開:

基本情報 科目B ソート(整列)のトレース練習

基本情報技術者試験の科目Bで、探索(線形探索・二分探索)と並んで必ず出会うのが ソート(整列) です。配列を小さい順(昇順)や大きい順(降順)に並べ替える処理で、出題頻度が高い一方、外側と内側の 2 つのループ(二重ループ) が登場するため「i と j のどちらが今どこを指しているのか分からなくなる」と一気につまずきます。本記事は、代表的な 選択ソート を変数の値を表に書きながら 1 行ずつ追う トレース で攻略する練習帳です。合計・最大値・線形探索のトレース練習・二分探索のトレース練習 の続編にあたります。

本記事は 過去問AI が学習用に作成したオリジナルの例題です。掲載している擬似言語は IPA の過去問・公式サンプルの転載ではなく、説明用に書き起こしたものです。擬似言語の正式な記述形式は必ず IPA 公式ページ で確認してください。記法そのものの読み方は 基本情報 科目Bの擬似言語 記法早見表 にまとめています。

選択ソートは「最小値を見つけて前へ運ぶ」整列

選択ソートは、まだ並んでいない範囲から最小値を探し、その範囲の先頭と交換する ことを繰り返す整列です。1 周ごとに「確定した先頭」が 1 つずつ増えていきます。たとえば 5 個の配列なら、1 周目で全体の最小値が先頭(1 番目)に確定し、2 周目で残り 4 個の最小値が 2 番目に確定し……と進み、4 周で並べ替えが完了します(最後の 1 個は自動的に確定するので、外側ループは要素数 − 1 回)。

この記事の例題は、すべて次の約束ごとで進めます(科目Bの標準的なルールです)。

  • 代入は ←(右の値を左の変数に入れる)。条件式の中の = は「等しいか?」の比較
  • 配列の 要素番号は 1 から始まる。A[1] が先頭、A[要素数] が末尾
  • min は「最小値そのもの」ではなく「最小値がある位置(添字)」 を覚える変数。実際の値は A[min] で取り出す

記法そのものが不安なら、先に 記法早見表 で ← の扱いを確認してから戻ってくるとスムーズです。

例題のコード

昇順に並べ替えたい配列 A = {5, 2, 8, 1, 9}(要素数 5)を、選択ソートで小さい順に整列するコードです。

整数型: i, j, min, tmp
for (i を 1 から 4 まで 1 ずつ増やす)
    min ← i
    for (j を i + 1 から 5 まで 1 ずつ増やす)
        if (A[j] < A[min])
            min ← j
        endif
    endfor
    if (min ≠ i)
        tmp ← A[i]
        A[i] ← A[min]
        A[min] ← tmp
    endif
endfor

読み方はこうです。外側の i は「これから確定させる位置」。まず min ← i として「今のところ i 番目が最小」と仮置きします。内側の j は i の 1 つ右から末尾までを順に見て、A[j] が今の最小値 A[min] より小さければ min を j に更新します。内側ループが終わると min には「i 番目以降で最も小さい値の位置」が入っているので、min が i と違う(=もっと小さい値が後ろにあった)ときだけ A[i] と A[min] を 交換 します。

内側ループの動き(i = 1 のとき)

まず外側 i = 1 の周回で、内側ループがどう最小値の位置を見つけるかを追います。min は i = 1(A[1] = 5)から始まります。

jA[j]現在の最小 A[min]A[j] < A[min]?更新後 min
開始前−A[1] = 5−1
j = 225はい2
j = 382いいえ2
j = 412はい4
j = 591いいえ4

内側ループが終わった時点で min = 4。つまり「1 番目以降で最も小さい値は 4 番目の A[4] = 1」と分かりました。min(4)≠ i(1)なので、A[1] と A[4] を tmp を使って交換します。配列は {1, 2, 8, 5, 9} になり、先頭の 1 が確定 しました。

外側ループ全体のトレース

同じ要領で外側 i = 1 〜 4 を回したときの、各周の結果だけをまとめます。「走査範囲 j」は内側ループが見る範囲、「min」は見つけた最小値の位置です。

i(確定する位置)走査範囲 j見つけた min交換交換後の配列
開始前−−−5, 2, 8, 1, 9
i = 12〜54(値 1)A[1] ↔ A[4]1, 2, 8, 5, 9
i = 23〜52(値 2)なし(min = i)1, 2, 8, 5, 9
i = 34〜54(値 5)A[3] ↔ A[4]1, 2, 5, 8, 9
i = 45〜54(値 8)なし(min = i)1, 2, 5, 8, 9

4 周終わって配列は {1, 2, 5, 8, 9} に整列しました。注目したいのは i = 2 と i = 4 では交換が起きていない 点です。すでに最小値がその位置にあるとき(min = i)は交換しません。ここで毎回必ず交換すると書いてしまうと、同じ値どうしを入れ替える無駄が出るだけでなく、設問によっては「交換回数」を問われたときに答えがずれます。

もう一つの定番:バブルソート

選択ソートと並んで頻出なのが バブルソート(隣接交換法) です。こちらは「隣り合う 2 つを比べ、左が大きければ交換する」を端から端まで繰り返し、大きい値を泡のように後ろへ押し上げます。選択ソートが「1 周で 1 回だけ交換(最小値を前へ)」なのに対し、バブルソートは「1 周で何度も隣どうしを交換する」のが違いです。トレースのコツは同じで、二重ループの i・j を表の列に固定し、交換のたびに配列の状態を 1 行書く こと。まずは交換が 1 周 1 回で追いやすい選択ソートで二重ループの感覚をつかむのがおすすめです。

つまずきやすい3つのポイント

  1. min は「値」ではなく「位置(添字)」。min に A[i] のような値を入れてしまうと、後で A[min] と書いたときに添字として使えず破綻します。比較は A[j] < A[min]、交換は A[min] と、つねに「位置を介して値を取り出す」と意識します。
  2. 交換は tmp を使う 3 行。A[i] ← A[min] を先に実行すると A[i] の元の値が消え、続く A[min] ← A[i] では両方が同じ値になって壊れます。必ず tmp ← A[i] で退避してから入れ替えます。
  3. 内側ループは i + 1 から始める。i 番目自身は「仮の最小」として基準にしているので、比べる相手は i の 1 つ右からです。j を i から始めると自分自身と比較する無駄が出ます(壊れはしませんが意図がぶれます)。

トレースで詰まらないためのコツ

二重ループは、表の 列を i・j・min・配列の状態 と決めてしまう のが最大のコツです。外側 i が 1 つ進むたびに区切り線を引き、その中で内側 j を 1 行ずつ動かすと、「今は何番目を確定させる周回で、内側はどこまで見たか」が一目で分かり、迷子になりません。配列の状態は交換が起きた行にだけ書き換えれば十分です。

次のステップ

ソートが追えるようになったら、出題範囲のアルゴリズムを一通りトレースで体験するのが近道です。基礎の 合計・最大値・線形探索のトレース練習、半分ずつ絞り込む 二分探索のトレース練習 をまだ見ていなければ先にそちらを、最難関の 再帰のトレース練習 ではコールスタックの上り下りを階乗で 1 段ずつ追えます。読む速度を上げる訓練法は 基本情報科目B|擬似言語アルゴリズム読解の3ステップ訓練法 で扱っています。つまずきが記法なのかトレースなのか切り分けたいときは 科目Bがわからない人へ、科目B 全体の進め方は 基本情報技術者 科目B完全対策 が地図になります。

手を動かす練習台としては、過去問AI の 基本情報 アルゴリズムとプログラミング分野の過去問 が使えます(こちらは科目A 相当の選択式で、科目B そのものの形式ではない点だけ意識してください)。各問題ページの AI コパイロットに「この選択ソートのコードを i・j・min を列にした表で 1 行ずつトレースして」と頼めば、本記事と同じ追い方を対話でその場で再現できます。

よくある質問

Q. 選択ソートの min には最小値そのものを入れるのですか? いいえ。min に入れるのは「最小値がある位置(添字)」です。値そのものではありません。最小値の実際の数は A[min] と書いて取り出します。位置で覚えておくと、最後に A[i] と A[min] を交換するときにそのまま添字として使えます。min に値を入れてしまうと A[min] が添字として成立せず破綻するので、「min は場所、A[min] が中身」と区別してください。

Q. なぜ交換に tmp という変数を使うのですか? 2 つの箱の中身を入れ替えるには、一方を一時的に避けておく場所が必要だからです。tmp を使わず A[i] ← A[min] を先に実行すると、A[i] の元の値が上書きされて消え、続く A[min] ← A[i] では両方が同じ値になってしまいます。必ず tmp ← A[i] で退避し、A[i] ← A[min]、最後に A[min] ← tmp の 3 行で入れ替えます。

Q. 内側ループはなぜ i ではなく i + 1 から始めるのですか? i 番目はその周回で「仮の最小値」として基準にしているため、比べる相手は i の 1 つ右からで十分だからです。j を i から始めると A[i] と A[i] を比較する無駄な 1 回が入ります。壊れはしませんが、IPA の設問では開始位置が i + 1 になっていることが多いので、コードの for の範囲をそのまま読み取る習慣をつけてください。

Q. 選択ソートとバブルソートはどちらが出ますか? どちらも科目Bで頻出で、過去のサンプル問題でも整列は定番テーマです。選択ソートは「最小値を見つけて 1 周に 1 回だけ交換」、バブルソートは「隣どうしを比べて何度も交換」と動きが違うため、両方の動きを 1 度ずつトレースしておくと安心です。まずは交換回数が少なく追いやすい選択ソートで二重ループの読み方に慣れるのがおすすめです。

まとめ

  • 選択ソートは 未整列の範囲から最小値を見つけ、その先頭と交換 する整列。外側ループは要素数 − 1 回
  • min は 最小値の「位置(添字)」。値は A[min] で取り出す
  • 交換は tmp を使う 3 行。tmp なしだと値が消えて壊れる
  • 内側ループは i + 1 から 末尾まで。min = i のときは交換しない
  • 二重ループは i・j・min・配列の状態を表の列に固定 し、外側が進むたびに区切って 1 行ずつ追う

線形探索 → 二分探索 → ソートとトレースで追えるようになれば、科目Bのアルゴリズム設問の主要パターンはひと通り読めるようになります。

基本情報技術者 の過去問で実戦演習する

記事の内容を実戦で確認しましょう。AI コパイロット付きで分からない点はその場で解決できます。

この記事に関連する過去問

関連記事

※ 本記事は 過去問AI が独自にまとめた学習ガイドです。試験要項の最新情報は必ず IPA 公式ページで確認してください。