ノーム
ソートは、
ソートアルゴリズムの一種であり、その動作は挿入
ソートに類似しています。しかし、要素の移動方法において、挿入
ソートのように要素を挿入するのではなく、バブル
ソートのように隣接する要素を交換していく点が異なります。この
アルゴリズムの名前は、オランダの庭にいるノーム(妖精)が植木鉢を並び替える様子に由来しています。
ノームソートの動作原理
ノーム
ソートは、以下の手順で要素を
ソートします。
1.
比較と交換: 現在位置の要素とその一つ前の要素を比較します。もし前の要素が現在の要素より大きい場合、二つの要素を交換します。
2.
後退: 要素を交換した場合、現在の位置を一つ前の位置に戻します。これにより、交換した要素が正しい位置に移動するまで、前の要素と比較・交換を繰り返します。
3.
前進: 要素を交換しなかった場合、現在の位置を一つ進めます。これにより、次の要素の比較に進みます。
4.
終了: 現在の位置が
配列の末尾に到達したら、
ソートは完了です。
この
アルゴリズムは、非常にシンプルで、複雑な制御構造を必要としません。
擬似コードで表すと以下のようになります。
pascal
procedure gnomeSort(a : array of integer)
var
i : integer := 1;
begin
while i < length(a) do
if (i = 0) or (a[i-1] <= a[i]) then
i := i + 1;
else
swap(a[i], a[i-1]);
i := i - 1;
end if;
end while;
end;
計算量と性能
ノーム
ソートの平均時間計算量はO(n^2)であり、これは挿入
ソートと同じです。しかし、実際の実行時間においては、挿入
ソートとほぼ同等の性能を発揮することが知られています。特に、ほぼ
ソート済みのデータに対しては、非常に高速に動作します。
特徴
シンプルさ:
アルゴリズムが非常に簡単で、実装が容易です。
インプレースソート: 追加のメモリ領域をほとんど必要としないインプレース
ソートです。
*
ストリーム処理: 全体のデータを事前に読み込む必要がないため、標準入力やパイプラインからのデータストリームに対して、並行して
ソート処理を行うことができます。これは、ノームが植木鉢を並び替えている最中でも、新しい植木鉢が追加されても問題なく
ソートが完了する様子に例えられます。
例
以下に、`4, 2, 7, 3` という
配列を昇順に
ソートする際の、ループ内の動作を示します。
1. `4 2 7 3` (初期状態)
2. `4 2 7 3` (4と2を比較。逆順なので交換)
3. `2 4 7 3` (交換したので前に戻る)
4. `2 4 7 3` (先頭なので次に進む)
5. `2 4 7 3` (4と7を比較。正順なので次に進む)
6. `2 4 7 3` (7と3を比較。逆順なので交換)
7. `2 4 3 7` (交換したので前に戻る)
8. `2 4 3 7` (4と3を比較。逆順なので交換)
9. `2 3 4 7` (交換したので前に戻る)
10. `2 3 4 7` (2と3を比較。正順なので次に進む)
11. `2 3 4 7` (3と4を比較。正順なので次に進む)
12. `2 3 4 7` (4と7を比較。正順なので次に進む)
13. `2 3 4 7` (最後まで調べたので終了)
このように、ノーム
ソートは単純な比較と交換を繰り返すことで、効率的に
配列を
ソートします。その分かりやすさと実装の容易さから、教育目的や小規模なデータセットの
ソートに利用されることがあります。