未整列部分の中から最小値を探して、先頭と交換する操作を繰り返します。 毎回「最小値を選択(select)する」ことからこの名前がついています。
○ selection_sort(整数型の配列: a)
整数型: i, j, min_idx, tmp
整数型: n ← a の要素数
for ( i を 1 から n - 1 まで 1 ずつ増やす )
min_idx ← i // 未整列部分の先頭を暫定最小とする
for ( j を i + 1 から n まで 1 ずつ増やす )
if ( a[j] が a[min_idx] より小さい )
min_idx ← j // より小さい要素が見つかれば位置を更新
endif
endfor
// min_idx の要素を先頭(i)と交換
tmp ← a[i]
a[i] ← a[min_idx]
a[min_idx] ← tmp
endfor
min_idx は「最小値の位置(添字)」を覚えておく変数です。
最小値の値ではなく位置を記録し、1パス終了後に1回だけ交換するのが選択ソートの特徴です。
バブルソートは 隣り合う要素を比べ、大きい方を右へ移動させる ことを繰り返すソートです。 1回のパスで最大値が末尾に「泡(バブル)のように浮き上がる」ことが名前の由来です。
選択ソートが「最小値を先頭に持ってくる(1パス1交換)」のに対して、 バブルソートは「最大値を末尾に押し出す(比較のたびに交換が起きる)」イメージです。
a[j] と a[j+1] の隣接比較・交換があればバブル、
min_idx で最小値の位置を探していれば選択ソートです。
| ソート | 動きのイメージ | 1パスの交換 | 計算量 |
|---|---|---|---|
| 選択ソート | 最小値を探して先頭へ | 1回 | O(n²) |
| バブルソート | 隣を比べて大きい方を右へ | 複数回 | O(n²) |
選択ソートで「1パスごとに行う操作」はどれか。
選択ソートで {5, 3, 4, 1, 2} を昇順に並び替えるとき、パス1(i=1)終了後の配列はどれか。
次の選択ソートのコードで、変数 min_idx の役割として正しいものはどれか。
min_idx ← i
for ( j を i + 1 から n まで 1 ずつ増やす )
if ( a[j] が a[min_idx] より小さい )
min_idx ← j
endif
endfor
min_idx ← j は「最小値の位置(添字)」を記録しています。値ではなく位置を覚えるのがポイントです。a[i] と a[min_idx] を交換するために位置が必要です。
min_idx ← i と初期化されていることから、ア(パス番号)やエ(回数)ではないと分かります。
次のコードはバブルソートと選択ソートのどちらか。
for ( i を 1 から n - 1 まで 1 ずつ増やす )
min_idx ← i
for ( j を i + 1 から n まで 1 ずつ増やす )
if ( a[j] が a[min_idx] より小さい )
min_idx ← j
endif
endfor
tmp ← a[i]
a[i] ← a[min_idx]
a[min_idx] ← tmp
endfor
min_idx で最小値の位置を記録し、内側ループが終わってから1回だけ交換する構造が選択ソートの特徴です。a[j] と a[j+1] を比べてループ内で交換することです。
このコードには隣接比較も内側での交換もありません。
配列 a = {4, 2, 7, 1, 5} に対して選択ソート(昇順)を実行する。
外側ループ 1 回目(i=1)が終わった直後の配列はどれか。
for ( i を 1 から n - 1 まで 1 ずつ増やす )
min_idx ← i
for ( j を i + 1 から n まで 1 ずつ増やす )
if ( a[j] が a[min_idx] より小さい )
min_idx ← j
endif
endfor
tmp ← a[i]
a[i] ← a[min_idx]
a[min_idx] ← tmp
endfor
要素数 n=100 の配列に対して選択ソートを行うとき、
配列の比較はおよそ何回行われるか。