はじめに
ソートアルゴリズムの学習として、12種のソートアルゴリズムを実装して可視化してみました。
Unityにはあまり関係がなさそうな話題ですが、Unity上で作ったのでUnityタグをつけます。
バブルソート
バブルソートのアルゴリズムは以下のような感じです。
- 配列の要素を最初から最後まで見ていき、順序が逆の要素があれば入れ替える
- 全ての要素の順序が正しくなるまで 1.を繰り返す.
void BubbleSort(int[] a)
{
bool isEnd = false;
int finAdjust = 1; // 最終添え字の調整値
while (!isEnd)
{
bool loopSwap = false;
for (int i = 0; i < a.Length - finAdjust; i++)
{
if (a[i] < a[i + 1])
{
Swap(ref a[i], ref a[i + 1]);
loopSwap = true;
}
}
if (!loopSwap) // Swapが一度も実行されなかった場合はソート終了
{
isEnd = true;
}
finAdjust++
}
}
シェーカーソート
シェーカーソートはバブルソートを改良したソートアルゴリズムです。
バブルソートでは1方向にスキャンを行っていたところを、往復してスキャンするようにしたものです。
コムソート
コムソートはバブルソートを改良したソートアルゴリズムです。
アルゴリズムは以下になります。
- データ数n を 1.3 で割った整数部分を間隔 h とします。
- i を 0 -> n-h-1 でfor文で回します。
- i番目と i+h 番目を比べたときに順序が逆になっていた場合入れ替えます。
- 3.が完了したら、h を 1.3 で割った整数部分を新たなhとして再び2.と3.を行います。
- 4.が終了したときに h が 1になっていた場合、そこでソート完了です。
ノームソート
- 配列の要素を順方向へ順番に見ていきます。
- 順序が逆になっている要素を見つけたらその要素をつかみます。
- つかんだ要素を一つ手前の要素と交換します。交換した後も順序が逆だったらさらに手前にずらす・・・という操作を繰り返します。
- ずらし終わったら、その位置から再び順方向へ要素を見ていきます。
- 配列の最後の要素まで到達したらソート完了です。
選択ソート
配列の要素を順番に見ていき、要素を最大値と入れ替えていくことで整列を行います
挿入ソート
要素を適切な場所へ挿入することで整列を行います。
シェルソート
- 適当な間隔 h を決める
- 間隔 h をあけて取り出したデータ列に挿入ソートを適用する
- 間隔 h を狭めて、2.を適用する操作を繰り返す
h=1 になったら、最後に挿入ソートを適用して終了
クイックソート
大雑把なアルゴリズムは以下にようになります。
- 配列からピボットとして要素一つ選び、ピボットより左側のすべての要素は小さく、右側はピボットより大きくなるように互いを入れ替えていきます。
- ピボットの左側から新たなピボットを選び、1.を行います。 ピボットの右側からも新たなピボットを選び同様の操作を行いソートします。
- これらを繰り返すことでソートを行います。
バケットソート
- 配列の要素の値をインデックスとして直接バケツへ移動
- バケツの手前から順番に配列に戻してソート完了
基数ソート
要素の1の位でバケットソートをし、次に10の位でバケットソート、その次は100の位で...
といった感じに、桁に対応する数字でバケツソートを行うソートアルゴリズムです。
メモリ使用量がバケツソートよりも少なくて済みます。
ヒープソート
- 配列をヒープ構造にして、根元のノードの数字を取り出す。
- 再びヒープ構造にして1.を行う
- 全ての数字を取り出したらソート完了
ヒープ構造の特徴は以下になります。
- 二分木の根には必ず最大値がくる。
- 二分木の各親子関係の親ノードには必ず最大値がくる
マージソート
- 配列を2つに分割する
- 各々をソートする
- 二つのソートされた配列をマージする
おわりに
筆者はソートアルゴリズムについては疎いため、本記事には誤りがある可能性があります。
誤りを見つけた場合は教えていただけると助かります。
参考URL
ソート - Wikipedia
https://ja.wikipedia.org/wiki/ソート