本文へスキップ
totonoe.tech
雑学・読み物

ソートはなぜ何種類もあるのか──データが2倍で手間は4倍?比較回数で見るO記法

並べ替えの方法が何種類もあるのは、データの量や並びで速さが変わるからです。選択ソートは個数が2倍で比較が約4倍、マージソートは約2.5倍。O記法を比較回数の実測で読み、使い分けも整理します。

この記事のポイント

  • 選択ソートは個数が2倍で比較回数が約4倍、マージソートは約2.5倍
  • O記法は細かい係数を無視し、個数が増えたときの増え方の形だけを見る
  • 「アルゴリズムを整える」で5つのソートの比較回数を同じデータで比べられる
Q.
ソートのアルゴリズムはなぜ何種類もあるの?
A.
データの量や並び方、必要なメモリによって、速い方法が変わるからです。たとえばほぼ整列済みのデータは挿入ソートが速く、大量のデータはマージソートのような方法が向きます。どれか1つが常に最良とは言えないため、場面に応じて使い分けます。
この記事の作業は、無料のツールでそのままできます(入力は送信されません) アルゴリズムを整える 並べ替え・探し方・しまい方を図で 開く

名簿を点数の高い順に並べ替える。10人なら、手でも一瞬です。ところが同じ作業を1,000人でやろうとすると、急に途方もなく時間がかかるように感じます。人数は100倍なのに、手間が100倍で済むのか、それとももっと膨らむのか。

結論を先に書きます。

並べ替えの方法によって、データの量が増えたときの手間の増え方が違います。選択ソートは個数が2倍になると比較の回数が約4倍に、マージソートは約2.5倍になります。 増え方が違うので、どの方法を使うかで大量のデータを扱うときの待ち時間が大きく変わります。これが、ソートに何種類もの方法がある理由の核心です。

個数が2倍になると、比較は何倍になるか

実際に数えてみます。このサイトの「アルゴリズムを整える」と同じ数え方(要素どうしを比べる回数を1回と数える)で、ランダムな数字を並べて、個数を倍々にしてみました。

個数選択ソートマージソート
104523
2019065
40780170
803160417

選択ソートは、「残りの中から一番小さいものを探して左端に置く」を繰り返す方法です。比較の回数は、データの並びに関係なく n×(n−1)÷2 で決まります。10個なら45回、20個なら190回。個数が10から20に2倍になると、比較は190÷45で約4.2倍です。20から40では約4.1倍、40から80では約4.05倍と、倍率は4に近づいていきます。

マージソートは、半分に分けてそれぞれ並べてから、整列済みの2つの列を先頭から比べて合わせる方法です。個数が2倍になると、比較は約2.8倍、約2.6倍、約2.5倍と、2倍より少し多い程度で増えます。マージソートの数字は乱数で作った1回分の実測なので、並びが変わると多少ずれます。選択ソートのほうは、毎回同じ数になります。

この「増え方の形」を書き表すのが、O記法です。選択ソートは O(n²)、マージソートは O(n log n) と書きます。O(n²) は個数が2倍で4倍、O(n log n) は2倍より少し多い、という形を表します。

O記法は、細かい数を捨てて形だけを見る

O記法には、約束事があります。細かい係数や足し算の小さな項を無視して、個数が増えたときの増え方の形だけを見るという点です。

選択ソートの比較回数は正確には n(n−1)÷2 ですが、これを O(n²) と書きます。n が大きくなると、n² の部分が圧倒的に効いてくるからです。個数が1,000なら、n² は1,000,000、n log₂n は約9,966です。この差は100倍あまりです。

個数が10のときは、n²が100、n log₂nが約33で、差は小さく見えます。ところが1,000個になると差は大きく開きます。「小さいデータでは違いが目立たないが、大きくなるほど効いてくる」。これがO記法で比べる意味です。

ちなみに、比較で並べ替える方法には、速さの限界があります。10個の並べ方は10!=3,628,800通りあり、1回の比較で可能性を最大でも半分にしか絞れないので、どんな方法でも、最悪の並びでは少なくとも22回の比較が必要です(log₂(3,628,800)≒21.8の切り上げ)。上の表のマージソートの23回は、この限界にかなり近い数字です。

それでも別の方法が残っている理由

では、いつもマージソートを使えばよいのでしょうか。そうとも言えません。ソートの方法ごとに、得意・不得意があります。

方法得意なこと弱点・注意点
バブルソート仕組みが単純。交換がなければ途中で終えられる平均・最悪は O(n²)
選択ソート交換の回数が少ない(多くても n−1 回)比較の回数は並びによらず O(n²)
挿入ソートほぼ整列済みのデータでは比較が少ない(最良 O(n))逆順に近いと O(n²)
クイックソート平均で O(n log n)。作業用の領域が小さい基準の選び方が悪いと最悪 O(n²)
マージソート最悪でも O(n log n)。同じ値の順番を保つ(安定)作業用の配列が n 個ぶん必要

たとえば、毎日少しずつ追加される名簿を、すでに並んだ状態に差し込むなら、挿入ソートが向いています。メモリが乏しい機器なら、作業用の配列が要らない方法が候補になります。「同点の人は元の名簿順のままにしたい」なら、安定な方法を選びます。

つまり、ソートの方法が何種類もあるのは、データの量・並び・メモリ・安定性という条件が現場ごとに違うからです。実際のプログラミング言語に用意されている並べ替えの機能は、こうした条件を踏まえて、複数の方法を組み合わせて作られていることもあります。

動かして、回数を比べる

文章だけだと実感しにくいので、同じデータで5つの方法を動かして、比較の回数を見比べてみてください。アルゴリズムを整えるは、バブル・選択・挿入・クイック・マージの5つを棒グラフで1手ずつ動かし、比較と交換の回数を並べて表示します。データを「ほぼ整列済み」「逆順」「同じ値が多い」に変えると、得意な方法が入れ替わる様子も見えます。

基本情報技術者試験で O 記法を聞かれても、やることは同じです。「個数が2倍になったら、手間は何倍か」を考えます。2倍なら O(n)、4倍なら O(n²)、2倍より少し多いなら O(n log n)。その見当がつけば、まず困りません。

運営サイト

私たちが運営するサイト