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


単純挿入法(シェル・ソートの基本)


並び替えの基本ロジックの2回目です。
今回は、シェル・ソートの基本的部分「単純挿入法」を取り上げてみます。




単純挿入法の考え方


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

この「単純挿入法」のロジックは簡単に言うと、2番目の数字から自分より前の数字と大小比較を始めて、自分の置かれるべき場所(常に自分より前)に移動していくものです。
例えば、3番目の数字が一番小さいとしますと、3番目の数字は1番目に移動し、1〜2番目の数字は1つずつ後ろに移動します。 これは3番目の数字が一番前に挿入された形ですので、「挿入法」という名前が付いたのだと思われます。

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

例:50,30,20,40,10 の5つの数字を、小さい順に並べ替えます。

  1. 2番目の数字30から始めます。
    自分の前の数字と比較して、自分の置かれるべき位置を見つけます。

  2. 自分(今は2番目の数字30)の前の数字は、1番目の数字50です。
     ↓──↓
    50,30,20,40,10

    自分(30)は50より小さいので1番目に入り、50は1つ後ろにずれます。
    すると、30,50,20,40,10となります。
    もし1番目の数字が自分より小さかったら、何もしません。


  3. 次は3番目で、前の数字と比較して、自分の置かれるべき位置を見つけます。


  4. まず自分(3番目の数字20)の前の数字の、1番目の数字30と比較します。
     ↓─────↓
    30,50,20,40,10

    自分(20)は30より小さいので1番目に入り、30と50は1つずつ後ろにずれます。
    すると、20,30,50,40,10となります。

    もし1番目の数字が自分より小さかったら、2番目の数字と比較します。
    もし1番目の数字も2番目の数字も、自分より小さかったら、何もしません。


  5. 次は4番目で、前の数字と比較して、自分の置かれるべき位置を見つけます。


  6. まず自分(4番目の数字40)の前の数字の、1番目の数字20と比較します。
     ↓────────↓
    20,30,50,40,10
    自分(40)は20より大きいので、何もしません。 もし自分が1番目の数字より小さかったら、自分が1番目に挿入されることは、わかりますね。

  7. 自分(4番目の数字40)の前の数字の、2番目の数字30と比較します。
        ↓─────↓
    20,30,50,40,10
    自分(40)は30より大きいので、何もしません。 もし自分が2番目の数字より小さかったら、自分が2番目に挿入されることは、書かなくてもよいですよね。

  8. 自分(4番目の数字40)の前の数字の、3番目の数字50と比較します。
           ↓──↓
    20,30,50,40,10

    自分(40)は50より小さいので3番目に入り、50は1つずつ後ろにずれます。
    すると、20,30,40,50,10となります。


  9. さて、最後の5番目で、前の数字と比較して、自分の置かれるべき位置を見つけます。


  10. 自分(5番目の数字10)の前の数字の、1番目の数字20と比較します。
     ↓───────────↓
    20,30,40,50,10

    自分(10)は20より小さいので1番目に入り、1〜4番目の数字は1つずつ後ろにずれます。 大移動ですね。
    すると、10,20,30,40,50となります。

    これで、小さい順に並び終わりましたが、プログラム上は「1番目の数字が自分より大きい場合」や、 「2〜4番目の数字が自分より小さい場合」などを考慮に入れるべきなのは言うまでもありません。

このロジックは、前回の「選択法」や、初級2の練習4の「交換法」と比べて、難しいでしょうか? 今のところ、どれが一番易しそうですか?

さて、ロジックは理解できたとしまして、いよいよこれをプログラムにするわけですが、 どんなプログラムになるか、わかりますか?




ループなしのプログラム


プログラム的には、一番難しいかもしれません。 何故なら、3重のループになるからです。
でもまず、ループを意識しないで、ループなしで考えてみましょう。 (実は、ループなしだと、とても大変なのですが・・・)

  1. 小さいほうの数字を入れる変数を宣言します。
    Dim Smaller  As Long '小さいほうの数字


  2. 2番目の数字から始めます。
    自分(今は2番目の数字)の前の数字は、1番目の数字です。
    1番目の数字と大小比較します。
    If Cells(1, 2) < Cells(1, 1) Then  '2番目の数字が1番目の数字未満なら
      自分は1番目に入り、もとの1番目の数字は1つ後ろにずれます。
      Smaller = Cells(1, 2)      '小さいほうの数字 ← 2番目の数字
      Cells(1, 2) = Cells(1, 1)    '2番目 ← 1番目の数字
      Cells(1, 1) = Smaller      '1番目 ← 小さいほうの数字
    End If      '自分のほうが大きい場合は、何もしない


  3. 次は、3番目の数字です。
    自分(3番目の数字)と1番目の数字とを、大小比較します。
    If Cells(1, 3) < Cells(1, 1) Then  '3番目の数字が1番目の数字未満なら
      自分は1番目に入り、もとの1〜2番目の数字は1つずつ後ろにずれます。
      Smaller = Cells(1, 3)      '小さいほうの数字 ← 3番目の数字
      Cells(1, 3) = Cells(1, 2)    '3番目 ← 2番目の数字
      Cells(1, 2) = Cells(1, 1)    '2番目 ← 1番目の数字
      Cells(1, 1) = Smaller      '1番目 ← 小さいほうの数字
    Else      '自分のほうが大きい場合は、次へ


  4. 3番目の数字が1番目の数字より大きい場合、2番目の数字と大小比較します。
      If Cells(1, 3) < Cells(1, 2) Then  '3番目の数字が2番目の数字未満なら
        自分は2番目に入り、もとの2番目の数字は1つ後ろにずれます。
        Smaller = Cells(1, 3)      '小さいほうの数字 ← 3番目の数字
        Cells(1, 3) = Cells(1, 2)    '3番目 ← 2番目の数字
        Cells(1, 2) = Smaller      '2番目 ← 小さいほうの数字
      End If      '自分のほうが大きい場合は、何もしない
    End If      'If と End If の数を合わせること


  5. 4番目の数字の番です。
    自分(4番目の数字)と1番目の数字とを、大小比較します。
    If Cells(1, 4) < Cells(1, 1) Then  '4番目の数字が1番目の数字未満なら
      自分は1番目に入り、もとの1〜3番目の数字は1つずつ後ろにずれます。
      Smaller = Cells(1, 4)      '小さいほうの数字 ← 4番目の数字
      Cells(1, 4) = Cells(1, 3)    '4番目 ← 3番目の数字
      Cells(1, 3) = Cells(1, 2)    '3番目 ← 2番目の数字
      Cells(1, 2) = Cells(1, 1)    '2番目 ← 1番目の数字
      Cells(1, 1) = Smaller      '1番目 ← 小さいほうの数字
    Else      '自分のほうが大きい場合は、次へ


  6. 4番目の数字が1番目の数字より大きい場合、2番目の数字と大小比較します。
      If Cells(1, 4) < Cells(1, 2) Then  '4番目の数字が2番目の数字未満なら
        自分は2番目に入り、もとの2〜3番目の数字は1つずつ後ろにずれます。
        Smaller = Cells(1, 4)      '小さいほうの数字 ← 4番目の数字
        Cells(1, 4) = Cells(1, 3)    '4番目 ← 3番目の数字
        Cells(1, 3) = Cells(1, 2)    '3番目 ← 2番目の数字
        Cells(1, 2) = Smaller      '2番目 ← 小さいほうの数字
      Else      '自分のほうが大きい場合は、次へ
  7. 4番目の数字が2番目の数字より大きい場合、3番目の数字と大小比較します。
        If Cells(1, 4) < Cells(1, 3) Then  '4番目の数字が3番目の数字未満なら
        自分は3番目に入り、もとの3番目の数字は1つ後ろにずれます。
          Smaller = Cells(1, 4)      '小さいほうの数字 ← 4番目の数字
          Cells(1, 4) = Cells(1, 3)    '4番目 ← 3番目の数字
          Cells(1, 3) = Smaller      '3番目 ← 小さいほうの数字
        End If      '自分のほうが大きい場合は、何もしない
      End If      'If と End If の数を合わせること
    End If      'If と End If の数を合わせること



説明は、ここまでにします。 5番目の数字の場合どうするかは、各自で考えて完成させてください。
さらには Do 〜 Loop を使って、5つの数字でなく、もっとたくさんの数字の並び替えができるようにしてください。

3重のループになると書きましたが、まずは1重のループから考えてみてください。

ヒントは・・・ここ↓
  Smaller = Cells(1, 4)      '小さいほうの数字 ← 4番目の数字
  Cells(1, 4) = Cells(1, 3)    '4番目 ← 3番目の数字
  Cells(1, 3) = Cells(1, 2)    '3番目 ← 2番目の数字
  Cells(1, 2) = Cells(1, 1)    '2番目 ← 1番目の数字
  Cells(1, 1) = Smaller      '1番目 ← 小さいほうの数字
1つずつ ずらすところですね。

もう1つヒントを。
今までは、ループカウンター(i など)を 1 ずつ足していきましたが、今回は 1 ずつ引いていってください。

それでは、また次回まで!




戻る

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


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