整列(ソート)アルゴリズムの比較
バブル・選択・挿入・クイック・マージ・ヒープ・シェル・基数の8つの整列法を説明文から見分け、バブルソートの交換の順番、選択ソートの比較回数、シェルソートと基数ソートの手順を自力で追えるようになる。
整列は「説明文を読んでどの方法か当てる」問題が毎回のように出ます。特にクイックソートは本試験でも繰り返し出題されています。手順を追う問題も、動きを一度つかめば確実に取れる得点源です。
このレッスンで稽古する(用語チェック・過去問)まず全体像:8つの整列法を一言で
整列(ソート)は、データを小さい順(昇順)か大きい順(降順)に並べ替える処理です。試験に出るのは、整列法の説明文を読んで名前を当てる問題がほとんどです。下の表の「一言でいうと」を言えるようにすれば、名前当ての問題は解けます。
| 整列法 | 一言でいうと | 説明文に出るキーワード |
|---|---|---|
| バブルソート | 隣どうしを比べ、順番が逆なら入れ替える | 「隣り合う要素を比較」「逆順なら交換」 |
| 選択ソート | 残りから最小値(最大値)を探し、先頭に置く | 「最小値を求め、それを除いた部分からまた最小値を求める」 |
| 挿入ソート | 整列済みの列の正しい位置に、1つずつ差し込む | 「整列済みのデータ列の正しい位置に追加」 |
| クイックソート | 基準値より小さいグループと大きいグループに分け、それぞれで繰り返す | 「基準値」「大きいグループと小さいグループに分割」「再帰的」 |
| マージソート | 細かく分けてから、整列しながら合体(併合)させる | 「併合」「マージ」 |
| ヒープソート | 未整列部分をヒープ(順序木)にし、根から最大値(最小値)を取り出して整列済みに移す | 「順序木」「最小値を取り出して整列済みに移す」 |
| シェルソート | 一定の間隔おきの要素で整列し、間隔を詰めながら繰り返す | 「ある間隔おきに取り出した要素」「間隔が1になるまで」 |
| 基数ソート | 1の位、10の位…と桁ごとにグループ分けして並べ直す | 「1の位の値で0〜9のグループに分ける」 |
ヒープソートは前のレッスンで学んだヒープを使います。ヒープは「親が子より必ず大きい(小さい)」木なので、根を取ればいつでも最大値(最小値)が手に入ります。
クイックソート:最頻出。「基準値で2つに分ける」
クイックソートは、ピボット(基準値)を1つ選び、それより小さい値のグループと大きい値のグループに分けます。分けた各グループの中でもまたピボットを選び、同じ分割を繰り返します。このように、同じ手順を小さい範囲に当てはめて繰り返すことを再帰といいます。
たとえるなら、クラスを「160cm未満」と「160cm以上」の2組に分け、それぞれの組をまた基準を決めて半分に分けていくやり方です。最後は1人ずつになり、全員が身長順に並びます。
flowchart TD
A["5, 3, 8, 1, 9, 2(基準値 5)"] --> B["5より小さい: 3, 1, 2"]
A --> C["5"]
A --> D["5より大きい: 8, 9"]
B --> E["さらに基準値を選んで分割 → 1, 2, 3"]
D --> F["さらに分割 → 8, 9"]
- 平均すると速い整列法です(計算量は n log n に比例。計算量とは、データ数 n が増えたとき手間がどれだけ増えるかの目安)。
- 基準値が毎回端の値になると、分割が偏って遅くなります(最悪は n² に比例)。そのため、前半と後半が同じくらいの大きさになる基準値を選ぶのが望ましいとされます。
マージソートとの見分け方:クイックソートは「先に大小で分ける」方法で、合体の操作はありません。マージソートは「とにかく半分に分け、整列しながら併合する」方法です。説明文に「併合」とあればマージソート、「基準値」とあればクイックソートです。
バブルソート:隣どうしの比較と交換
バブルソートは、隣り合う2つを比べて、順番が逆なら入れ替えます。これを端から端まで1回行うことを1パスと呼びます。泡(バブル)が水面に浮かぶように、値が1つずつ端へ運ばれるのが名前の由来です。
1パス後に何が決まるかは、走査の向きで決まります。
| 走査の向き | 小さい順に並べるとき、1パス後に確定するもの |
|---|---|
| 先頭 → 末尾 | 最大値が末尾 A[n] に来る |
| 末尾 → 先頭 | 最小値が先頭 A[1] に来る |
大きい値は交換のたびに後ろへ運ばれるので、先頭から走査すると最大値が末尾まで運ばれます。逆に末尾から走査すると、小さい値が前へ運ばれて最小値が A[1] に来ます。擬似コード(プログラムを日本語風に書いたもの)の問題では、内側ループの変数が n から減っていくか、増えていくかをまず確認しましょう。
選択ソート:比較回数は n(n−1)/2
選択ソートは、未整列部分から最小値(大きい順なら最大値)を探し、未整列部分の先頭と交換します。これを繰り返すと、先頭から順に確定していきます。
比較回数は、データの並び方に関係なく次のとおりです。
- 1回目:残り n 個から探すので n−1 回比較
- 2回目:n−2 回 … 最後は 1 回
- 合計:(n−1)+(n−2)+…+1 = n(n−1)/2
例:n=5 なら 4+3+2+1 = 10 で、5×4÷2 = 10 と一致します。迷ったら n=2 や n=3 を代入して確かめると確実です(n=3 なら比較は2回+1回=3回で、3×2÷2 = 3)。
シェルソートと基数ソート:手順を追う問題
シェルソートは、挿入ソートの改良版です。まず離れた間隔 H ごとの部分列を挿入法で整列し、H を小さくしながら繰り返し、最後は H=1(ふつうの挿入ソート)で仕上げます。遠くの要素を先に大まかに動かしておくので、最後の挿入ソートの手間が少なくて済みます。
基数ソートは、大小の比較をしません。代わりに、1の位の数字で0〜9のグループに分けて並べ直し、次に10の位で同じことをする、と下の桁から順に処理します。グループの中では前の順番を崩さないのがルールで、これがあるから最後の桁まで処理すると全体が整列します。
どちらの問題も、問われているのは「途中でどうなるか」です。最後まで整列が終わった答え(きれいに並んだ選択肢)に飛びつかず、問題が指定した手順のところで止めましょう。
バブルソートで2回目に交換されるデータ
ア 3 と 7
イ 4 と 5
ウ 4 と 7
エ 5 と 7
出典:基本情報技術者試験 科目A免除 修了試験 20260726 実施分 問6
解き方と答えを見る
- データ列は 2, 7, 3, 5, 6, 8, 4, 1。先頭から隣どうしを比べ、左の方が大きければ交換する。
- 2 と 7 を比べる:2 < 7 なので交換しない。
- 7 と 3 を比べる:7 > 3 なので交換(1回目)。列は 2, 3, 7, 5, 6, 8, 4, 1 になる。
- 7 と 5 を比べる:7 > 5 なので交換(2回目)。列は 2, 3, 5, 7, 6, 8, 4, 1 になる。
- 2回目に交換されたのは 5 と 7。
答え:エ(5 と 7)。3 と 7 の交換は1回目なので、アは誤り。
末尾から走査するバブルソートの1パス後
ア A[1]が最小値になる。
イ A[1]が最大値になる。
ウ A[n]が最小値になる。
エ A[n]が最大値になる。
出典:基本情報技術者試験 科目A免除 修了試験 20220612 実施分 問9
解き方と答えを見る
- 外側ループ i=1 のとき、内側ループの j は n から i+1=2 まで、1ずつ減っていく。
- j=n のときは A[n] と A[n−1]、次は A[n−1] と A[n−2]…と、末尾から先頭に向かって比べる。
- A[j] < A[j−1] のときに交換するので、小さい値ほど前へ運ばれる。
- 最小値は、どこにあっても交換を重ねて前へ運ばれ、j=2 の比較で A[1] に入る。
- したがって、行2〜3が初めて終わったとき、A[1] は必ず最小値になっている。
答え:ア(A[1] が最小値になる)
選択ソートの比較(α印)の実行回数
ア n(n-1)/2
イ n(n-1)
ウ n(n+1)/2
エ n(n+1)
出典:基本情報技術者試験 科目A免除 修了試験 20110626 実施分 問7
解き方と答えを見る
- 外側ループ「交換」は、i が 1 から n−1 まで回る。
- 内側ループ「最大値」は、j が i+1 から n まで回る。1回まわるごとに α の比較が1回行われるので、比較回数は n−i 回。
- i=1 のとき n−1 回、i=2 のとき n−2 回、…、i=n−1 のとき 1 回。
- 合計は (n−1)+(n−2)+…+1 = n(n−1)/2。
- 確認:n=3 のとき 2+1 = 3 回。式に代入すると 3×2÷2 = 3 で一致する。
答え:ア(n(n−1)/2)
シェルソートで手順(3)を実行する回数
ア 2
イ 3
ウ 4
エ 5
出典:基本情報技術者試験 科目A免除 修了試験 200907 実施分 問5
解き方と答えを見る
- データ数は 9。手順(1)で H = [9÷3] = 3 とする。
- 手順(2)で、間隔3の部分列をそれぞれ挿入法で整列する。
- 手順(3)で H = [3÷3] = 1 とする(1回目)。
- 手順(4)で H は 0 ではないので、(2)に戻る。H=1 で全体を挿入法で整列する。
- 手順(3)で H = [1÷3] = 0 とする(2回目)。
- 手順(4)で H が 0 になったので完了。手順(3)の実行は合計2回。
答え:ア(2回)。H=1 で整列した後にも(3)を1回実行することを数え忘れないこと。
基数ソートで10の位まで処理した結果
ア 180,282,315,410,525,645
イ 315,410,525,180,282,645
ウ 410,315,525,645,180,282
エ 645,525,410,315,282,180
出典:基本情報技術者試験 科目A免除 修了試験 200912 実施分 問7
解き方と答えを見る
- 元の並びは 180, 315, 282, 410, 645, 525。
- 手順1:1の位でグループに分ける。0のグループは 180, 410、2のグループは 282、5のグループは 315, 645, 525(グループ内は元の順を保つ)。
- 手順2:0→2→5 の順に並べると 180, 410, 282, 315, 645, 525。
- 手順3:この並びを10の位で分ける。1のグループは 410, 315、2のグループは 525、4のグループは 645、8のグループは 180, 282。
- 手順4:1→2→4→8 の順に並べると 410, 315, 525, 645, 180, 282。
答え:ウ(410,315,525,645,180,282)。100の位はまだ処理していないので、全体は整列しきっていない。
要点(試験直前に読む)
- 説明文のキーワードで見分ける:隣り合う比較交換=バブル、最小値を選ぶ=選択、正しい位置に挿入=挿入、基準値で大小に分割=クイック、併合=マージ、順序木=ヒープ、間隔おき=シェル、桁ごとにグループ分け=基数。
- クイックソートは「基準値で小さいグループと大きいグループに分け、再帰的に繰り返す」。前半と後半が同じくらいの大きさになる基準値を選ぶのが望ましい。
- バブルソートで1パス後に確定するのは端の値。先頭から走査すると最大値が末尾に、末尾から走査すると最小値が先頭に来る。
- 選択ソートの比較回数は (n−1)+(n−2)+…+1 = n(n−1)/2。迷ったら n=3 を代入して確かめる。
- シェルソートと基数ソートの手順問題は、問題が指定したところで止めて答える。
ひっかけ
- 説明文の名前当ての問題では、残りの3つの選択肢に別の整列法の説明が並ぶ。表のキーワードと一つずつ照らし合わせれば消去できる。
- バブルソートの1パス後の問題は、走査の向きを逆に読ませるのが狙い。内側ループの変数が n から減るなら、最小値が A[1] に来る。
- 「何回目の交換」を問う問題は、交換しなかった比較を数えてしまうとずれる。交換が起きたときだけ数える。
- 選択ソートの比較回数で n(n+1)/2 や n(n−1) を選ばせる。ループの範囲(i は n−1 まで、j は i+1 から)を確認し、小さな n を代入して検算する。
- シェルソートでは、H=1 で整列した後の H=0 にする手順(3)を数え忘れやすい。基数ソートでは、整列済みに見える選択肢に飛びつかないこと。10の位までしか処理していなければ、100の位はばらばらのまま。
用語(13)
データを決まった順序(昇順・降順)に並べ替える処理。
⚠ 探索(データの中から目的の値を探す処理)とは別のもの。2分探索などは整列済みのデータを前提にする。
隣り合う2つの要素を比べ、順番が逆なら交換する操作を繰り返す整列法。
⚠ 選択ソートは「最小値を探して先頭と交換」で、交換する相手が隣とは限らない。「隣り合う」とあればバブルソート。
整列の途中で、データ列を端から端まで1回走査すること。
未整列部分から最小値(最大値)を選び、未整列部分の先頭と交換することを繰り返す整列法。
⚠ 挿入ソートは「整列済みの列に1つずつ差し込む」。選択ソートは「残りから最小値を探す」。
整列済みの列の正しい位置に、未整列の要素を1つずつ差し込んでいく整列法。
⚠ 選択ソートと混同しやすい。キーワードは「正しい位置に挿入(追加)」。
基準値より小さいグループと大きいグループに分け、各グループで同じ分割を再帰的に繰り返す整列法。
⚠ マージソートも分割するが、整列しながら「併合」する。説明文に基準値があればクイックソート、併合があればマージソート。
クイックソートで、グループを大小に分けるときの境目として選ぶ値。
ある処理の中で、より小さな範囲に対して同じ処理を呼び出して繰り返すこと。
データを細かく分けてから、整列しながら合体(併合)させていく整列法。
⚠ クイックソートとの見分け方は「併合」の有無。
未整列部分をヒープ(順序木)にし、根から最大値(最小値)を取り出して整列済みに移すことを繰り返す整列法。
⚠ 選択ソートも最小値を取り出すが、最小値を探す手段が違う。「順序木」「ヒープ」とあればヒープソート。
一定の間隔ごとの要素で部分列を作って挿入法で整列し、間隔を詰めながら最後は間隔1で仕上げる整列法。
⚠ 「ある間隔おきに取り出した要素」とあればシェルソート。基数ソートの「桁ごと」と混同しない。
下の桁から順に、桁の数字でグループに分けて並べ直すことを繰り返す整列法。大小の比較はしない。
⚠ 「1の位で0〜9に分ける」とあれば基数ソート。途中の桁までしか処理しなければ、まだ整列は終わっていない。
データ数 n が増えたとき、処理の手間がどの程度増えるかの目安。
⚠ バブル・選択・挿入は n² に比例。クイック(平均)・マージ・ヒープは n log n に比例。
このレッスンの過去問
- バブルソートの定義(隣接要素の比較交換)基本情報技術者試験 科目A免除 修了試験 20221211 実施分 問8
- バブルソートの1パス後の状態基本情報技術者試験 科目A免除 修了試験 20260726 実施分 問6
- 選択ソートの比較回数基本情報技術者試験 科目A免除 修了試験 20110626 実施分 問7
- クイックソートのアルゴリズム令和8年度 基本情報技術者試験 科目A 公開問題 問2
- シェルソートの手順トレース基本情報技術者試験 科目A免除 修了試験 200907 実施分 問5
- 基数ソートの手順トレース基本情報技術者試験 科目A免除 修了試験 200912 実施分 問7