For faster navigation, this Iframe is preloading the Wikiwand page for 選択ソート.

選択ソート

選択ソート
Selection Sort Animation
Selection Sort Animation
クラス ソート
データ構造 配列
最悪計算時間 О(n²)
最良計算時間 О(n²)
平均計算時間 О(n²)
最悪空間計算量 О(n) total, O(1) auxiliary

選択ソート: selection sort)は、ソートアルゴリズムの一つ。 配列から最小値を探し、配列の先頭要素と入れ替えていくことで並べ替える。

最良時間計算量O(n2) と遅いため、一般にはクイックソートなどのより高速な方法が利用される。しかし、空間計算量が限られるため他の高速な手法が使えない場合や、ソートする配列が充分小さく、選択ソートが高速に動作することが保証されている場合に利用されることがある。

選択ソートは内部ソートである。また、安定ソートではない。

選択ソートの改良として、ヒープソートが挙げられる。

アルゴリズム

[編集]
Selection-Sort-Animation

選択ソートは以下の手順で行う:

  1. 1 番目の要素から最後尾の要素までで最も値の小さいものを探し、それを 1 番目の要素と交換する(1番目の要素までソート済みとなる)
  2. 以降同様に、未ソート部分の最小要素を探索し、未ソート部分の先頭要素と交換する
  3. すべての要素がソート済みになったら処理を終了する

上記は昇順への並べ替えだが、降順の場合も同様に、最小値でなく最大値を検索することで実現できる。

また、各ループ毎に最小値と最大値との両方を探し、両端の要素を同時に確定させる手法もあり、double selection sortと呼ばれる。

擬似コード

[編集]
for I := 1 to N
  min := I
  for J := I+1 to N  
    if data[J] < data[min] then
      min := J
    end if
  end for
  swap(data[I], data[min])
end for

動作例

[編集]

初期データ: 8 4 3 7 6 5 2 1 

太字はソート完了した部分

1 4 3 7 6 5 2 8 (1回目のループ終了時)
1 2 3 7 6 5 4 8 (2回目のループ終了時)
1 2 3 7 6 5 4 8 (3回目のループ終了時)
1 2 3 4 6 5 7 8 (4回目のループ終了時)
1 2 3 4 5 6 7 8 (5回目のループ終了時)
この例では、一見して、この時点で既にソート完了したとわかる。しかしデータが多数の場合はそうはいかないし、アルゴリズムで「一見して」ソート完了か否か判断できない。アルゴリズム通りに最後まで処理する必要がある。
1 2 3 4 5 6 7 8 (6回目のループ終了時)
1 2 3 4 5 6 7 8 (7回目のループ終了時)

計算時間

[編集]

以下、ソートする配列の要素数を n とする。

要素の比較に関して、各ループで n − 1 回、n − 2 回、……と行われ、処理全体としては 回行われる。

要素の交換に関して、各ループで最大1回行われ、処理全体では多くとも n − 1 回となる。

バブルソートと比較すると、要素の比較回数は同じだが交換回数が少ないため、選択ソートの方が高速である。

安定性

[編集]

選択ソートは安定ソートではなく、複数の同値の要素を持つ配列に対して、同値の要素同士の順序は保存されない。 例えば配列 (2a 2b 1) に対して選択ソートを行うと、

2a 2b 1 (初期状態)
1 2b 2a (1回目のループ終了時)
1 2b 2a (2回目のループ終了時)
1 2b 2a (終了状態)

となる(2a, 2b は同値とする)。ソートの前後で 2a, 2bの順序が変更されており、安定でないことが確かめられる。

実装

[編集]

Python

[編集]

Python での実装例を示す。 In-place 版の実装は以下の通り。

def minIndex(x, i):
    mi = i
    for j in range(i + 1, len(x)):
        if x[j] < x[mi]:
            mi = j
    return mi

def swap(x, i, j):
    x[i], x[j] = x[j], x[i]

def inplaceSelectionSort(seq):
    for i in range(len(seq)):
        mi = minIndex(seq, i)
        swap(seq, i, mi)

非 in-place 版は上記に配列のコピーを渡すことで実現できるが、例えば以下のように直接実装することもできる。

def nonInplaceSelectionSort(seq):
    ind = [*range(len(seq))]
    res = []    
    for i in range(len(seq)):
        k = 0
        for j in range(len(ind)):
            if seq[ind[j]] < seq[ind[k]]:
                k = j
        res.append(ind.pop(k))
    return [seq[i] for i in res]

C#

[編集]

C# での実装は以下の通り。

namespace Algorithms
{
class SelectionSort
{
    static void sort(int[] x) {
        for(int i = 0; i < x.Length; i++) {
            int min = i;
            for(int j = i + 1; j < x.Length; j++) {
                if(x[j] < x[min]) {
                    min = j;
                }
            }
            int t = x[i];
            x[i] = x[min];
            x[min] = t;
        }
    }
}
}

Scheme

[編集]

Scheme での実装を以下に示す。

(require-extension srfi-1)              ; 実装依存。SRFI-1 と言うライブラリを用いる。

(define (selection-sort ls)
  (let loop ((ls ls) (acc '()))
    (if (null? ls)
        (reverse acc)
        (let ((x (apply min ls)))
          (loop (remove (lambda (y)
                          (= y x)) ls) (cons x acc))))))


{{bottomLinkPreText}} {{bottomLinkText}}
選択ソート
Listen to this article

This browser is not supported by Wikiwand :(
Wikiwand requires a browser with modern capabilities in order to provide you with the best reading experience.
Please download and use one of the following browsers:

This article was just edited, click to reload
This article has been deleted on Wikipedia (Why?)

Back to homepage

Please click Add in the dialog above
Please click Allow in the top-left corner,
then click Install Now in the dialog
Please click Open in the download dialog,
then click Install
Please click the "Downloads" icon in the Safari toolbar, open the first download in the list,
then click Install
{{::$root.activation.text}}

Install Wikiwand

Install on Chrome Install on Firefox
Don't forget to rate us

Tell your friends about Wikiwand!

Gmail Facebook Twitter Link

Enjoying Wikiwand?

Tell your friends and spread the love:
Share on Gmail Share on Facebook Share on Twitter Share on Buffer

Our magic isn't perfect

You can help our automatic cover photo selection by reporting an unsuitable photo.

This photo is visually disturbing This photo is not a good choice

Thank you for helping!


Your input will affect cover photo selection, along with input from other users.

X

Get ready for Wikiwand 2.0 🎉! the new version arrives on September 1st! Don't want to wait?