プログラミング初級
並べ替えの練習


単純交換法(バブル・ソートの基本)


並び替えの基本ロジックの3回目、最終回です。
今回は、バブル・ソートの基本的部分「単純交換法」です。




単純交換法の考え方


この練習では、Excel のセルを数字の入力域および出力域として利用します。
Sheet1 のセルA1〜A5 に、適当な整数を入れておいてください。

この「単純交換法」は、1回目の単純選沢法と、2回目の単純挿入法を合わせたようなものです。

単純選沢法 一番小さい数字を探して入れ替える
単純挿入法2番目の数字から自分より前の数字と大小比較を始めて、自分の置かれるべき場所(常に自分より前)に移動していく
単純交換法1番目の数字から始めて、自分より後ろの一番小さい数字を探して、自分の位置に挿入していく


つまり「単純交換法」は、単純選沢法の「一番小さい数字を探す」ロジックと、 単純挿入法の「数字を挿入する(後ろの数字をずらしていく)」ロジックを合わせたものです。

では、例を出してみましょう。

例:55,22,44,11,33 の5つの数字を、小さい順に並べ替えます。

  1. 1番目の数字55から始めます。
    自分より後ろのすべての数字2〜5番目で、一番小さい数字を探します。
        ↓────────↓
    55,22,44,11,33

    一番小さい数字は11で、1番目の数字55より小さいので、1番目に入ります。 それから、一番小さい数字より前の数字、55〜44は1つずつ後ろにずれます。
    すると、11,55,22,44,33 となります。
    もし1番目の数字が、後ろの「一番小さい数字」より小さかったら、何もしません。


  2. 次は2番目の数字です。
    自分より後ろのすべての数字3〜5番目で、一番小さい数字を探します。
           ↓─────↓
    11,55,22,44,33

    一番小さい数字は22で、2番目の数字55より小さいので、2番目に入ります。 それから、一番小さい数字より前の数字、55〜22は1つずつ後ろにずれます。
    すると、11,22,55,44,33 となります。
    もし2番目の数字が、後ろの「一番小さい数字」より小さかったら、何もしません。


  3. それから3番目の数字です。
    自分より後ろのすべての数字4〜5番目で、一番小さい数字を探します。
              ↓──↓
    11,22,55,44,33

    一番小さい数字は33で、3番目の数字55より小さいので、3番目に入り、55〜44は1つずつ後ろにずれます。
    すると、11,22,33,55,44 となります。
    もし3番目の数字が、後ろの「一番小さい数字」より小さかったら、何もしません。


  4. 次は4番目の数字です。
    自分より後ろの数字5番目で、一番小さい数字は・・・5番目ですね。
                ↓↓
    11,22,33,55,44

    5番目の数字44は、4番目の数字55より小さいので、4番目に入り、55は1つ後ろにずれます。
    すると、11,22,33,44,55 となります。
    もし4番目の数字が、5番目の数字より小さかったら、何もしません。


    これで、並び替わりました。 (^^)

    ここの説明では、数字を横に並べていますが、縦に並べて数字の動きを見てみます。

55
22
44
11
33
┌→
│ 
│ 
┘ 
 
11
55
22
44
33


11
55
22
44
33
  
┌→
┘ 
  
  
11
22
55
44
33


11
55
22
44
33
  
  
┌→
│ 
┘ 
11
22
33
55
44


11
22
33
55
44
  
  
  
┌→
┘ 
11
22
33
44
55


バブル・ソートは、いろいろな工夫を凝らして、もっと複雑なロジックになっているそうですが、基本は同じです。 数字を縦に並べて その動きを見ると、まるで水の中の泡のように、数字がポコポコ浮かび上がるように見えるので、 バブル(泡)ソートという名前が付いた・・・と聞きましたが、真偽の程はわかりません。(^^;

ロジックは理解できましたか?
これをプログラムにできますか?
1回目と2回目を合わせたものなので、プログラムも1回目と2回目を見てもらえば わかるのですが。




ループなしのプログラム


前回は、3重のループでしたが、今回は・・・さて?
でも前回と同様、まず、ループを意識しないで、ループなしで考えてみましょう。

  1. 一番小さい数字用の変数を宣言します。
    Dim min_suji  As Integer '一番小さい数字
    Dim min_no   As Integer '一番小さい数字が何番目か


  2. 1番目の数字から始めます。
    まず1番目の数字が一番小さいと仮定します。
    一番小さい数字の情報を、変数 min_suji, min_no にセットします。
    min_suji = Cells(1, 1)  'min_suji ← 1番目の数字
    min_no = 1        'min_no ← 1(番目)


  3. 後ろの一番小さい数字を探します。
    自分(今は1番目の数字)の後ろの数字は、2〜5番目の数字です。

    1. 2番目の数字と一番小さい数字を比較します。
      If Cells(1, 2) < min_suji Then
      もし2番目の数字のほうが小さいなら、2番目の数字の情報を、変数 min_suji, min_no にセットします。
        min_suji = Cells(1, 2)  'min_suji ← 2番目の数字
        min_no = 2        'min_no ← 2(番目)
      End If      '2番目のほうが大きい場合は、何もしない


    2. 3番目の数字と一番小さい数字を比較します。
      If Cells(1, 3) < min_suji Then
      もし2番目の数字のほうが小さいなら、3番目の数字の情報を、変数 min_suji, min_no にセットします。
        min_suji = Cells(1, 3)  'min_suji ← 3番目の数字
        min_no = 3        'min_no ← 3(番目)
      End If      '3番目のほうが大きい場合は、何もしない


    3. 4番目の数字と一番小さい数字を比較します。
      If Cells(1, 4) < min_suji Then
      もし4番目の数字のほうが小さいなら、4番目の数字の情報を、変数 min_suji, min_no にセットします。
        min_suji = Cells(1, 4)  'min_suji ← 4番目の数字
        min_no = 4        'min_no ← 4(番目)
      End If      '4番目のほうが大きい場合は、何もしない


    4. 5番目の数字と一番小さい数字を比較します。
      If Cells(1, 5) < min_suji Then
      もし5番目の数字のほうが小さいなら、5番目の数字の情報を、変数 min_suji, min_no にセットします。
        min_suji = Cells(1, 5)  'min_suji ← 5番目の数字
        min_no = 5        'min_no ← 5(番目)
      End If      '5番目のほうが大きい場合は、何もしない

      はい、これで一番小さい数字が、わかりましたね。


  4. 自分(今は1番目の数字)と、一番小さい数字を、大小比較します。
    If Cells(1, 1) < min_suji Then


  5. 1番目の数字が一番小さい数字未満なら、一番小さい数字は1番目に入り、一番小さい数字より前の数字は1つずつ後ろにずれます。
      If min_no = 5 Then
       '一番小さい数字が5番目なら、4番目の数字は5番目にずれます。
        Cells(1, 5) = Cells(1, 4)    '5番目 ← 4番目の数字
      End If      '5番目でないなら、何もしない

      If min_no => 4 Then
       '一番小さい数字が4番目以降なら、3番目の数字は4番目にずれます。
        Cells(1, 4) = Cells(1, 3)    '4番目 ← 3番目の数字
      End If      '4番目以降でないなら、何もしない

      If min_no => 3 Then
       '一番小さい数字が3番目以降なら、2番目の数字は3番目にずれます。
        Cells(1, 3) = Cells(1, 2)    '3番目 ← 2番目の数字
      End If      '3番目以降でないなら、何もしない

     '一番小さい数字は、当然2番目以降なので、1番目の数字は2番目にずれます。
      Cells(1, 2) = Cells(1, 1)      '2番目 ← 1番目の数字

     '一番小さい数字は、1番目に入ります。
      Cells(1, 1) = min_suji        '1番目 ← 一番小さい数字

    End If      '自分のほうが大きい場合は、何もしない



ふう、やっぱ ループを使わないのって、大変だ。 よって、説明は、ここまでにします。

まだ1番目の数字しか処理していませんが、1番目の数字が一番大変です。 あと、2〜4番目の数字の処理は、皆様が考えてください。
「え? 5番目の数字の処理は?」
と言う人がいたら・・・最後の数字の後ろに、いったいどんな数字があるのか、教えてください。(笑)

また Do 〜 Loop を使って、5つの数字でなく、もっとたくさんの数字の並び替えができるようにしてください。

さて何重のループになるでしょうか? まずは1重のループから考えてみてください。

ヒントは・・・一番小さい数字を探すところと、1つずつ数字をずらすところから、やってみてね。 それぞれ別のループになりますよ。





戻る

楽天モバイル[UNLIMITが今なら1円] ECナビでポインと Yahoo 楽天 LINEがデータ消費ゼロで月額500円〜!


無料ホームページ 無料のクレジットカード 海外格安航空券 解約手数料0円【あしたでんき】 海外旅行保険が無料! 海外ホテル