Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

Rubyでの選択ソートを理解する

注:これは、Rubyを使用したさまざまな並べ替えアルゴリズムを紹介するシリーズのパート2です。パート1ではバブルソートについて説明しました。

この投稿では、Rubyを使用して選択ソートアルゴリズムを実装する方法について説明します。選択ソートは、インプレース比較ソートアルゴリズムです。これは、ソートされたアイテムが元のアイテムと同じストレージを占有することを意味します。先に進む前に、データセットが小さい(つまり、10〜20要素)場合を除いて、選択ソートアルゴリズムは実際には一般的に使用されないことに注意することが重要です。ただし、自転車の前に三輪車に乗る方法を学ぶのと同じように、学習して理解するための優れたスターターアルゴリズムです。実装は、就職の面接のコーディングの課題に現れる場合があります。または、理由を説明するように求められる場合があります。 選択ソートのようなアルゴリズムは、大規模なデータセットではあまり実用的ではありません。選択ソートは通常、このシリーズで最初に検討したアルゴリズムであるバブルソートよりも優れています。

大まかに言えば、選択ソートは配列を2つの部分に分割します。1つは半分にソートされ、もう1つはソートされません。開始時に、ソートされたセクションは空であり、ソートされていない部分にはすべての要素が含まれています。選択ソートは2つのループを利用します。外側のループはn回繰り返されます。ここで、nは配列内の要素の数です。すぐに「最小インデックス」を最初の要素に設定し、次に別のループを使用して要素を比較し、隣接する要素が現在の最小値よりも小さい場合は最小インデックスを交換します。

これを理解するのが難しい場合でも、心配しないでください。次に、実際の例を見ていきます。 :)

ステップバイステップ

次の要素を持つ配列から始めましょう:[10, 30, 27, 7, 33, 15, 40, 50]

反復1:最小数を見つける

この場合、最小数は7です。 、それで最初に配置して10を移動します 7の場所へ だった。配列は次のようになります:[7, 30, 27, 10, 33, 15, 40, 50]

反復2:次に小さい数を見つける

インデックス位置1の要素から開始して(配列は0インデックスであることに注意してください)、次に小さい要素を見つけます

この場合は10. 10を移動します 配列の2番目の位置に移動し、30を移動します 10の場所へ だった。結果の配列は次のとおりです:[7, 10, 27, 30, 33, 15, 40, 50]

ここから、配列が完全にソートされるまで、この正確なプロセスを続行します。以下に、次の反復後の結果の配列を示します。

反復3:

[7, 10, 15, 30, 33, 27, 40, 50]

反復4:

[7, 10, 15, 27, 33, 30, 40, 50]

反復5:

[7, 10, 15, 27, 30, 33, 40, 50]

ビンゴ!ソートされています!

視覚的な学習者の方は、選択ソートが[]の配列でどのように機能するかの例を次に示します。

Rubyでの選択ソートを理解する 写真クレジット

Rubyの実装

これがRubyで書かれた選択ソート関数です:

def selection_sort(array)
  n = array.length - 1
  n.times do |i|
    min_index = i
    for j in (i + 1)..n
      min_index = j if array[j] < array[min_index]
    end
    array[i], array[min_index] = array[min_index], array[i] if min_index != i
  end
  puts array
end

これがどのように機能するかを見てみましょう。

まず、nを設定します 要素の数に等しい。配列は0インデックスであるため、1を引く必要があることを忘れないでください。

次に、nを実行する外部ループを作成します

min_index = i

ここでは、最初の位置にある要素に最小インデックスを設定しています。

for j in (i + 1)..n

次に、内側のループを作成します。この行は、「n番目の要素の2番目の位置にある要素について、次のことを実行します」と言っています。 ..に慣れていない場合 演算子を使用すると、始点から終点までの範囲が作成されます。例:1..10 1から10までの範囲を作成します。

min_index = j if array[j] < array[min_index]

このループ内で、min_indexを設定します 現在のmin_index未満の場合は、新しい要素に 。

array[i], array[min_index] = array[min_index], array[i] if min_index != i

内部ループの外側で、現在のmin_indexかどうかを確認します iと同じです 。これが本当なら、要素をシャッフルする必要があります。 array[i]を設定します array[min_index]へ およびarray[min_index] array[i]へ 。ここでは、例と同じように「スワップ」を実行しています。

最後に、終了したら、配列を出力します。これで並べ替えられます!

すべてをまとめる

これが私の完全なプログラムです:

def selection_sort(array)
  n = array.length - 1
  n.times do |i|
    min_index = i
    for j in (i + 1)..n
      min_index = j if array[j] < array[min_index]
    end
    array[i], array[min_index] = array[min_index], array[i] if min_index != i
  end
  puts array
end

array = [10, 30, 27, 7, 33, 15, 40, 50]

selection_sort(array)

ruby ruby-selection-sort.rbを実行しています 端末から次のように出力されます:

7
10
15
27
30
33
40
50

かっこいい!

選択ソートが非効率的である理由を理解する

アルゴリズムの効率を測定する1つの方法は、「Big-O表記」を調べることです。これは、アルゴリズムを比較できるように、最悪の場合のパフォーマンスを表します。たとえば、Big-OがO(1)のアルゴリズムは、最悪の場合の実行時間が要素数 "n"の増加に伴って一定であることを意味しますが、Big-O表記がO(n)のアルゴリズムは)は、nが大きくなるにつれて、最悪の場合の実行時間が直線的に増加することを意味します。つまり、100個の要素を持つ配列があり、O(n)とO(1)の並べ替えアルゴリズムを選択する必要がある場合、O(1)はO(100)よりも確実に優れているため、O(1)アルゴリズムを選択します。

バブルソートと同様に、選択ソートでは、ループがネストされているため、最悪の場合の平均的な複雑さはO(n ^ 2)になります。これは、要素の数が増えるにつれて効率が劇的に低下することを意味します。

まとめ

すべてを考慮すると、選択ソートは、コーディングの課題でポップアップする可能性のある興味深いアルゴリズムです。または、選択ソート機能が与えられ、Big-O表記とは何かとその理由を尋ねられる場合があります。この記事の例が、どちらのシナリオにも取り組む準備ができていることを願っています。


  1. Rubyでの挿入ソートを理解する

    注:これは、Rubyを使用したさまざまなソートアルゴリズムの実装を検討するシリーズのパート4です。パート1ではバブルソート、パート2では選択ソート、パート3ではマージソートについて説明しました。 データを並べ替えるためのさまざまな方法を引き続き検討するため、挿入並べ替えに目を向けます。挿入ソートが好きな理由はたくさんあります!まず、挿入ソートは安定です。 、これは、等しいキーを持つ要素の相対的な順序を変更しないことを意味します。 インプレースアルゴリズムでもあります 、は、並べ替えられた要素を格納するための新しい配列を作成しないことを意味します。最後に、挿入ソートは、すぐにわかるように、実

  2. Ruby Mapメソッドの使用方法(例付き)

    Mapは、配列、ハッシュ、範囲で使用できるRubyメソッドです。 マップの主な用途は、データを変換することです。 例 : 文字列の配列が与えられた場合、すべての文字列に目を通し、すべての文字を大文字にすることができます。 または、Userのリストがある場合 オブジェクト… 変換できます 対応するメールアドレス、電話番号、またはその他の属性のリストにそれらを追加します Userで定義 クラス。 これを行う方法を正確に見てみましょう! ルビーマップ構文 マップの構文は次のようになります: array = [a, b, c] array.map { |string| string.