第55回(最終回)
アルゴリズムの基礎・5~バブルソート

最後尾から並べ替える~バブルソート

連載の最後に、もう一度ソート――値の整列を試してみましょう。ちょっとひねった方法です。

最後尾から比べていく

本コラムの第51回で、数列の先頭から値を比較していく直接選択法を紹介しました。これは、並びの先頭の値を続く値と順次比較していくという、至極まっとうな方法でした。先のパズルで言えば、金貨を1枚ずつ取り出しては天秤で計る……というような感じで、仕組みは単純ですが手間がかかります。

探索では、金貨を何枚かの組に分けたように、値の並びを中間値で二分することで、手間を減らすことができました。整列では、この手は使えません。そこで、値の比較を先頭からではなく最後尾から行うことを試してみます。

1つ前の値と比較する

手順は次のようになります。

  1. 最後尾の値とその1つ前の値とを比較する
  2. 最後尾の値の方が小さければ
    → 値を入れ替える
    そうでなければ
    → 何もしない
  3. 最後尾の1つ前の値とさらにその1つ前の値とを比較する
         :
以下、同様に比較対象を1つずつ前に進め、
その1つ前の値と比較して、
比較元が小さければ値を入れ替えていく。

こうすることで、最も小さい値が並びの先頭に移動します。

次に、比較対象を最後尾から始めて先頭の次の次[3番目]まで繰り返します。すると、2番目に小さい値が並びの先頭に移動します。

カードで試してみる

このように、処理を1巡実行するたびに、比較対象の値は1個ずつ減っていきます。よって、同様の操作を「並びの数-1」回繰り返せば、すべての値が昇順に並びます。

第51回でサンプルに含めたカードを使って、実際にテーブル上で試してみましょう。カードは図1のように並んでいます。

※画面上でカードを並べ替えられるSilverlightアプリケーションを用意していますので、説明と合わせてお試しください。
» カード並べ替えアプリケーションを起動

図1:整列前のカード――第51回の図1と同じ
図1:整列前のカード――第51回の図1と同じ

1巡目(図2)
  1. 最後尾の4とその1つ前の1を比較
    → 4の方が大きいので何もしない
    カードの並び:6 3 2 7 1 4
  2. 最後尾から2番目の1とその1つ前の7を比較
    → 1の方が小さいので1と7の場所を入れ替える
    カードの並び:6 3 2 1 7 4
  3. 最後尾から3番目の1とその1つ前の2を比較
    → 1の方が小さいので1と2の場所を入れ替える
    カードの並び:6 3 1 2 7 4
  4. 最後尾から4番目の1とその1つ前の3を比較
    → 1の方が小さいので1と3の場所を入れ替える
    カードの並び:6 1 3 2 7 4
  5. 最後尾から5番目の1とその1つ前(先頭)の6を比較
    → 1の方が小さいので1と6の場所を入れ替える
    カードの並び:1 6 3 2 7 4
図2:並べ替えの1巡目
図2:並べ替えの1巡目

これで、最小値の「1」が列の先頭に移動しました。

2巡目
  1. 最後尾の4とその1つ前の7を比較
    → 4の方が小さいので4と7の場所を入れ替える
    カードの並び:1 6 3 2 4 7
  2. 最後尾から2番目の4とその前の2を比較
    → 4の方が大きいので何もしない
    カードの並び:1 6 3 2 4 7
  3. 最後尾から3番目の2とその1つ前の3を比較
    → 2の方が小さいので2と3の場所を入れ替える
    カードの並び:1 6 2 3 4 7
  4. 最後尾から4番目の2とその1つ前の3を比較
    → 2の方が小さいので2と6の場所を入れ替える
    カードの並び:1 2 6 3 4 7
  5. 最後尾から5番目の2とその1つ前(先頭)の1を比較
    → 1の方が大きいので何もしない
    カードの並び:1 2 6 3 4 7
これで、「2」が列の2番目に移動しました。

3巡目
  1. 最後尾の7とその1つ前の4を比較
    → 7の方が大きいので何もしない
    カードの並び:1 2 6 3 4 7
  2. 最後尾から2番目の4とその前の3を比較
    → 4の方が大きいので何もしない
    カードの並び:1 2 6 3 4 7
  3. 最後尾から3番目の3とその1つ前の6を比較
    → 3の方が小さいので3と6の場所を入れ替える
    カードの並び:1 2 3 6 4 7
これで、「3」が列の3番目に移動しました。

4巡目
  1. 最後尾の7とその1つ前の4を比較
    → 7の方が大きいので何もしない
    カードの並び:1 2 3 6 4 7
  2. 最後尾から2番目の4とその前の6を比較
    → 4の方が小さいので4と6の場所を入れ替える
    カードの並び:1 2 3 4 6 7
これで、「4」が列の4番目に移動しました。

5巡目
この例では最後の2個の値「6と7」が昇順になっていますが、それは偶然でしかありません。

  1. 最後尾の7とその1つ前の6を比較
    → 7の方が大きいので何もしない
    カードの並び:1 2 3 4 6 7
これで、すべての順序が確定しました。

ボトムアップのバブルソート

この処理を眺めると、1巡目に1、2巡目に2……と、小さな数が順に前方に押し出されるように見えます。この様子が、泡が底から水面へと上がってくるように見えることから、この手法を「バブルソート」と呼びます。

直接選択法が前方(項番号の若い方)から後方(項番号の多い方)へと視点を移動させるのに対して、バブルソートでは視点が後方から前方へと移動していきます。直接選択方はトップダウン・アプローチ、バブルソートはボトムアップ・アプローチということです。