Table of Contents
カウントのソート入門
ソートは、小数の既知の範囲で整数をソートするときに、非コンパリソンベースのソートアルゴリズムです。 比較ベースのソートとは異なり、Quicksort や Mergesort などの比較ベースのソートとは異なり、ペアウェイト要素の比較に依存し、ソートは、各異なる値の頻度をカウントすることによってソートされた順序を決定します。 このアプローチは、有利な条件下で線形時間複雑さを収穫し、入力ドメインが制限される多くのパフォーマンスクリティカルなアプリケーションに適した選択肢を作る。
アルゴリズムは、1954年にHarold H. Sewardによって記述され、コンピュータサイエンスの基礎技術を維持しました。そのシンプルさと効率性は、学生時代、グレード、または最も有利なスプレッドを持つ任意の整数データをソートするようなタスクに最適です。 補助ストレージを値範囲に比例して活用することにより、ソートは、O(nログn)の比較の低い境界を回避し、O(n + k)の達成時間が、kは入力値の範囲であるO(n + k)の達成。
ソートのカウント方法
ソートのカウントのコア機構は簡単です。入力配列に各値が表示される回数をカウントし、各要素の最終位置を計算します。このプロセスは3つの異なるフェーズで構成されています。
- :]] カウントするサイズ k (入力値の範囲) のカウント配列を作成し、ゼロに初期化します。 入力配列を繰り返し、各値のカウントを増加させます。
- []:[を計算する カウント配列をプレフィックスの配列に変換し、各要素がインデックスで、要素の累積数が少ないか、または等しい要素の総数を保持する。 このステップは、ソートされた出力の各異なる値の開始位置を決定します。
- [] 要素を並べる:[]]] 右から左へ入力配列をトレースし、出力配列の正しいインデックスを見つけ、そこに要素を配置し、カウントを宣言します。 最終的な出力は、入力のソートされたコピーです。
アルゴリズムは、元の変更されていない配列を新しいソートした配列を返します。] というバリアントは、Sort をカウントする場所にあるが、安定性やスペース効率を損なうため、ほとんど使われません。
Step-by-Step の一例
値が0から8の範囲である配列[[[4, 2, 8,3,3,1]をソートすることを検討してください。
- [Count:]] カウント配列サイズ9 (0–8) → [0,1,2,2,1,0,0,0,1]。 (Index 1は一度表示されます。インデックス2は2回、インデックス3は2回、インデックス4は一度にインデックス8回)。
- []プレフィックス・サッシ:] 累積→[0,1,3,5,6,6,6,6,7] に変換します。 それぞれが、ソートされた出力のその番号の開始位置を教えてくれます。
- [出力:]] 端からトラバース元の配列:最初の要素は1 →位置 = count[1] - 1 = 0 → output[0]=1、減少数[1]から0です。 次に3 →位置 = count[3] - 1 = 4 →出力[4]=3、カウント[3]=4です。 配置されるすべての要素まで続きます。 最終出力:[1,2,2,3,4,8]
この例では、ソートのカウントが完全に比較を避け、算術操作だけに依存する方法を示しています。
計算の複雑さ
時間の複雑さ
- []ベスト、平均、ワーストケース:[] O(n + k)、nは要素数とkが入力値の範囲です。 kがnに比べると、アルゴリズムは線形時間で動作します。
- []比較ソートと比較して比較:[クイックソートとマーゲソートは、O(nログn)平均複雑さを持っています。 n = 106とk = 1000の場合、ソート(≈ 1,001,000操作)は、典型的なO(nログn)ソートよりも約13倍高速です。
宇宙の複雑さ
- [:]] カウント配列のO(k)、出力配列のO(n)。 kが大きい場合、このメモリオーバーヘッドは禁止できます(例えば、k = 232)。
- [] 安定的 variant:] は、補助出力配列のサイズ n が必要です。 代わりに、バリアントは安定性を犠牲にしたり、複雑なインデックス操作を使用する。
カウントソートを使用するときに
ソートのカウントは、次の条件下で最も効果的です。
- 入力は整数(または文字や離散的なカテゴリなど、小さな整数範囲にマッピングできるデータ)で構成されます。
- 範囲 k は n よりも大きくない。 親指の一般的なルールは k ≤ O(n) である。
- メモリは、カウント配列と出力バッファが余分スペースを必要とするため、ひどく制約を受けません。
- 安定性が必要です(例:複数のキーでソート)。 要素が右から左に置かれたときに標準の実装は安定しています。
優れた使用例には、ソートグレード(0〜100)、年齢(0〜120)、製品カテゴリ(最大数百SKS)、またはのサブルーチンとしてRadixソートが含まれます。
制限事項と留意事項
速度にもかかわらず、ソートのカウントは、その適用可能性を制限する欠点を持っています。
- []整数のみ:[]]] 連続整数セットに変換される場合を除き、フローティングポイント番号または文字列を直接ソートすることはできません。
- [] の大きい範囲:]] の k の dwarfs n が 1 と 107 の間の値で 100 の数値をソートした場合、数の配列は数要素だけをソートしながら、巨大なメモリを消費します。
- [非適応:[]]]) カウントソートは、データのソートが既にまたはほぼソートされている場合でも、常に入力全体をスキャンし、カウント配列をビルドする必要があります。
- []:[]]]]標準カウントソートは、非負の整数を想定しています。負を処理するには、最小値(範囲0を最大にするために-分)を割くことによって、値を変更できます。
これらの制限は、ソートをカウントするという特殊なツールではなく、汎用アルゴリズムの普遍的な交換を意味します。
関連ソートアルゴリズムとの比較
カウント ソート対ラディックス ソート
Radixソートは、各デジタルで安定したソート(多くの場合、カウントソート)を使用して、少なくとも重要な数字から最も重要な数字をソートすることによって、アイデアを拡張します。 ソートは、フルレンジのkを超えるパスに1つのパスを1つのパスで出力する一方で、Radixソートは、より小さな数字範囲(例えば、ベース256)を超える複数のパスを実行し、大きなkのメモリ使用量を削減します。 例えば、ソートは32ビット整数でソートすると、ソートは、分割されたエントリが8ビットのエントリが8ビットのエントリのみを渡す必要があります。
カウント ソート対. バケット ソート
Bucket ソートは、要素を複数の Bucket に配布し、各 Bucket を個別にソートします(多くの場合、インサートソート)。 ソートをカウントすると、各 Bucket が単一の異なる値に対応する Bucket の特別ケースとして表示できます。 Bucket ソートは、均一に分散されたフローティングポイントデータでうまく動作しますが、ソートのカウントは整数ドメインに限定されます。
安定したカウントのソートを実装する
別のキーから等しい要素の相対的な順序を予約している間、一キーによって分類するとき安定性は重要です。 出力配置ループが右から左に入力を横断するとき、標準カウントソートアルゴリズムは本質的に安定しています。 ここに安定した変形のテキストの輪郭があります:
- 計算配列を記述する。
- プレフィックス合計(ソートされた出力の各値の位置)に変換します。
- 逆順に入力配列を反復します。各要素は、そのカウントで示されている位置で、カウントを宣言します。
エンドから要素を処理するため、与えられた値の最後の発生は可能な限り最高に行なわれ、相対的な順序を予約します。この安定したバージョンは、各デジタル上で正しく機能するためにRidesのソートに不可欠です。
実用的応用
- ] 条件のグラデーション システム:[ 数百の試験スコア(範囲0〜100)をO(n)時間に並べ替える。
- [:[]]]] 整数または、アルファベットサイズが小さい(A、C、G、T) の場合の DNA k-mer の周波数をソートします。
- [データベースのインデックスのメンテナンス:[]]] 独自の整数識別子を範囲内でソートして、メモリに収まるのに十分小さい。
- []画像処理:] リストグラムのビンまたは色の強度(0〜255)を並べて、検索テーブルをビルドするときに。
- []二次キーによるソート:[は、さまざまなライブラリと言語で効率的なソートのための作業場であるRadixソート内で使用されます(例えば、.NETランタイムは、小さな範囲のソートをカウントするを含むアルゴリズムの適応ミックスを使用します)。
理論と変種の詳細については、 []] などの権威的な参照を参照してください。Wikipedia: カウントソート] と ]] の GeeksforGeeks: カウントソート[[[]]]]] を参照してください。他のアルゴリズムとの実用的な比較は、 で見つけることができます。
カウントの最適化 大規模範囲のソート
k が大きいが n も大きすぎると、純粋なカウントソートはメモリ・インテンシブになります。いくつかの最適化が存在します。
- []圧縮された間隔:[]は、使用した値の範囲が大きいが、異なる値の数が小さい場合、連続した配列の代わりにハッシュマップを使用します。 この取引は、ハッシュオーバーヘッドの定常時間インデックスが取引されますが、メモリ消費を削減します。
- []ハイブリッドアプローチ:[ 別のアルゴリズムでソートを結合します。例えば、範囲が106を超えた場合は、デジットが小さい範囲を保持するベースでRidesソートを使用します。
- [] の 変数:[]] の いくつかの最適化は、出力配列なしで O(k) に余分スペースを削減しますが、 それらは一般的に安定性を犠牲にしたり、位置を見つけるためにサイクルを要求します。
コンテンツ
カウントソートは、値範囲が要素の数に比べると、整数をソートするための、驚くべき効率的なアルゴリズムとして際立っています。そのO(n + k)の時間の複雑さとリニアパフォーマンスは、グレードソート、Ridesソートサブルーチン、および境界整数キーを持つアプリケーションなどのシナリオで不可欠です。しかし、アルゴリズムの整数に依存して、大規模な範囲のメモリオーバーヘッドは、すべての状況でソートが最適でないことを思い出させます。 計算:[Felt]と[Felt]を調べるときに、 [Felt]:[Felt]を解読解]: [Felt] と [F] を予測する: [Felt] [F] と [F] は、 [Felt] を予測します。