選択ソート
[Wikipedia|▼Menu]

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

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

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

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

選択ソートの改良として、ヒープソートが挙げられる。
アルゴリズムSelection-Sort-Animation

選択ソートは以下の手順で行う:
1 番目の要素から最後尾の要素までで最も値の小さいものを探し、それを 1 番目の要素と交換する(1番目の要素までソート済みとなる)

以降同様に、未ソート部分の最小要素を探索し、未ソート部分の先頭要素と交換する

すべての要素がソート済みになったら処理を終了する

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

また、各ループ毎に最小値と最大値との両方を探し、両端の要素を同時に確定させる手法もあり、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 回、……と行われ、処理全体としては ∑ k = 1 n − 1 k = n ( n − 1 ) 2 {\displaystyle \sum _{k=1}^{n-1}k={\frac {n(n-1)}{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 midef 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))))))











ソート
理論

計算複雑性理論

ランダウの記号

全順序

リスト

安定性

ソーティングネットワーク

比較ソート(英語版)

整数ソート(英語版)

交換ソート

バブルソート

シェーカーソート

奇偶転置ソート

コムソート

ノームソート

クイックソート

選択ソート

選択ソート

ヒープソート

スムースソート

デカルト木ソート

トーナメントソート

挿入ソート

挿入ソート

シェルソート

ツリーソート

図書館ソート

ペイシェンスソート

マージソート

マージソート

多層マージソート

ストランドソート

非比較ソート

基数ソート

バケットソート

計数ソート

プロキシマップソート

鳩の巣ソート

バーストソート

ビーズソート

並行ソート

バイトニックソート

バッチャー奇偶マージソート

シェアソート

混成ソート

ティムソート

イントロソート

Jソート

アンシャッフルソート(英語版)

その他

トポロジカルソート

パンケーキソート

スパゲティソート

非効率的/
ユーモラスソート

ボゴソート

ストゥージソート

スリープソート

エラーソート

カテゴリ


記事の検索
おまかせリスト
▼オプションを表示
ブックマーク登録
mixiチェック!
Twitterに投稿
オプション/リンク一覧
話題のニュース
列車運行情報
暇つぶしWikipedia

Size:10 KB
出典: フリー百科事典『ウィキペディア(Wikipedia)
担当:undef