エキゾチックなソーティング方法の貯金箱では、もう1つ、少し独特ですが、十分にランダムなデータを使用して適切な速度を提供します。
1からnまでのn個の正の整数のセットNがあるとします。
n個の数値を格納するには、 n個のセルが必要であることは自明です。 数字が書かれる順番に関係なく。
ソース配列
3 | 5 | 2 | 1 | 8 | 4 | 7 | 6 | 9 | 10 |
順序付けられていないセットNを順序付けられたセット(昇順または降順)に簡単に置き換えることができ 、順序付けられていないセットの代わりに順序付けられたセットを書くことは容易に想像できます。
順序付き配列
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
同様に、条件n max -n min = nを満たす数のセット(正の整数に制限します)を「ソート」できます。
より複雑なケースを考えてみましょう。
セットN (再び、正の整数)がn max -n min > nであり、セット内のすべての数値n(i)が異なるようにします。
30 | 55 | 21 | 17 | 82 | 46 | 79 | 63 | 94 | 108 |
このセットをソートするには、次のものが必要です。
1) n max 、 n minを見つける
2)デルタd =(n max -n min )/ nを計算する
3) n(i)ごとに(以下の手順は、条件付きで「石の散布」と呼ばれます):
3a)インデックスindx =(n(i)-n min )/ d + 1を計算します(計算も整数で想定されるため、丸めを補正し、ゼロインデックスを削除するために単位が追加されます)
数字n(i)とindx indは、これらの数字が立つべき場所です。
30 | 55 | 21 | 17 | 82 | 46 | 79 | 63 | 94 | 108 |
2 | 5 | 1 | 1 | 7 | 4 | 7 | 5 | 9 | 10 |
3b)ゼロで満たされたインデックスIndxsの事前に準備された配列で、前のステップで取得したインデックスでセルをインクリメントします
2 | 1 | 0 | 1 | 2 | 0 | 2 | 0 | 1 | 1 |
3c)結果の値を読み取る
3d)それにnを掛けてインデックスを追加し、このアドレスで配列Nに新しい数n(i)を書き込む
同一のインデックスが見つかった場合、配列N newの n(i)は下ではなく下から書き込まれます。
21 | 30 | 46 | 55 | 82 | 94 | 108 | |||
17 | 63 | 79 |
4)その後、「石のコレクション」に進みます
i = 1とし、インデックスIndxsの配列を順番に読み取ります。 ただし 、 i≤n
4a) Indxs(i) = 0の場合、次のiに進みます
4b) Indxs(i) = 1の場合、配列N newから数値を読み取り、ソートされた配列に出力し、次のiに進みます
4c) Indxs(i) = 2の場合、「垂直に」書き込まれたN個の数値を読み取り、それらを比較して、小さい方から大きい方へと順に印刷し、次のiに進みます
4d) Indxs(i) = 3の場合、3つの数値を読み取り、それらの中から最小値を見つけ、それを印刷してリストから削除し、残りの2つを比較して、すでに印刷します。
4e) Indxs(i) = 4の場合、すべてが同じです。最初に最小値の4を見つけ、それを消してから、インデックス3についても同じことを行います。
4e) Indxs(i)が 4より大きい場合、アルゴリズムを再帰的に呼び出します。
並べ替えられた配列
17 | 21 | 30 | 46 | 55 | 63 | 79 | 82 | 94 | 108 |
操作の数を推定してみましょう。
最小値と最大値を検索するには、1回のパス-n回の操作が必要です。
「石の散乱」にはn個の操作があります。
費用の「石の収集」は投入量に依存します。 この場合、数値のペアを比較するには、 n個のコピーと3つの操作が必要です。
random.orgから受信したn = 10000のセットでテストすると(リソースは1セットで10000を超える数を与えない)、アルゴリズムは次の統計を表示します。
n max = 10000の場合。 すべてのインデックス= 1、並べ替えは配列を3回通過して行われます。
n max = 11000の場合。 ゼロのほぼ半分:4547、906の単位、2:4547、トリプルなど:0同じ3つのパスに加えて、2つの数値のn回の比較のほぼ半分。
n max = 21000の場合ゼロ:3967 1:2845 2:2409 3:779 4:0
n max = 31000の場合:0:3881 1:3134 2:2197 3:680 4:108 More_than_four:0
n max = 101000 max in index:6ゼロ:3729 1:3541 2:1923 3:643 4:139 More_than_four:25
2回目の反復の呼び出しは25回のみです。
直観的には、最悪のシナリオでは、 n / 5回の反復が実行されます。
平均して、手っ取り早く、操作の数は4nのオーダーです。
このソート方法は、比較なしのソートグループに属し、ハンドヘルドソートとカウントソートの中間バージョンです。
カウントによる並べ替えの主な問題は、1つのセルに含まれる値を追加で並べ替える必要があることです。セル内の数字の数が4を超えると、それが重要になります。
しかし、まず、単位と数字のペアにより、ハンディキャップがあります。
第二に、バーストの数は通常1%未満の比較的少ないものです。
第三に、すでに2回目の反復で、バーストは非常にうまく処理されています。 さらに、入力データに繰り返しがないという制限は自動的に削除されます。 同じ値からバーストに遭遇した場合、デルタはd =(n max -n min )/ n = 0であり、バースト全体を出力に安全にコピーできます。
正の整数だけでなく、このソート方法の適用可能性の問題も完全に解決可能です。
もちろん、この方法には、より多くの侵入と落とし穴の特定が必要です。
利点:
スピード、理解とプログラミングの容易さ。
短所:
入力データに応じて、かなり大きなメモリ要件。 N個の新しいアレイをより合理的に編成することで、何を補おうとすることができますか。 いずれにしても、メモリには少なくとも3nが必要です。
UPD:
GitHubでFortコードをテストする