時間複雑線形でソートアルゴリズムをチャット

実際、時間複雑度は、O(nlogで制限比較および交換ソートアルゴリズムに基づく2 N-)。など言うまでもなく、時間複雑バブルソート、挿入ソート、O(N-される2も、クイックソートのような強いなど)、ヒープの並べ替えは、また達しのみO(nlog 2 N-複雑さ)の。そして、伝説的なO(nlogを突破できる方2 N-)制限は、エンドそれが何であるかでソートアルゴリズムの線形時間計算量はO(n)に、さんが詳しく見てみましょう。

バケットソート

基本的な考え方

文は、各要素は、バケットの限られた数に割り当てられた列構成のマッピング関数により各バケットソートした後の要素をソートする、です。
基本手順は次のとおりです。

  1. 空のバケツ準備の限られた数
  2. 各マッピング関数により槽内の対応する要素に割り当て、ソートする列を横切ります
  3. 各バケットは空の並べ替えではありません
  4. 各バケットから元の配列に要素が続く空されていません

バケットソート機能マッピングが分割素子を使用して行われ、交換を比較するステップが省略され、次いで、少量のデータをタブで行われ、ソートは、本明細書に、このような高速の並べ替えを使用して、実際のニーズに応じて任意のソートアルゴリズムを選択することができます。マップ選択機能が各タブは、すなわち、バケットのすべての要素が別のバケットのすべての要素より大きいかそれ以下である必要があり、順序付けされていることを確認しなければならないことに注意してください。秩序の要素を確実にするために、バケット内の各要素から元のシーケンスを戻すために、このように。

長所と短所の複雑さと安定性

  • 空間複雑:O(M + N)、mはバケットの数を表し、nは補助空間nの必要な長さとして表されます

  • 時間の複雑さ:O(n)の
    バケットソート時間のかかる2つの主要部分:

    1. 全ての要素は、バケットに列をソートされ、Oの時間複雑度(N)
    2. アルゴリズムは、比較に基づいているため、各バレル要素を並べ替え、平均時間計算量は、O(Nに到達することができ、私はログ2 N Iを、N)Iは、各槽内の要素の数であります

    :列の場合Nは次のようにソート平均時間計算を表現することができるバケット元素、Mバケット、各バケット平均N / M元素、ソートされるべき
    O(N)+ O(M *が(N / M)がログ2 (N / M) )、M == Nは、複雑さはO(N)

  • 好ましくは、ケース:ソートするエレメント列が均等槽に分配されているO(n)は、線形時間O(N)です。各バレル少ないデータが少ない時間をソートするために使用されるが、対応する領域の消費量が増加します。各バケット唯一つの要素、すなわち、浴槽の最良の順序M == Nは、実際のO(N)に達したとき

  • 最悪の場合:全ての要素が同じバケットに割り当てられている、通常のソートにバケットソートが変性。

  • 安定性:安定

  • 長所:安定した、ソートの比較に基づいて下限を壊します

  • 短所:追加のサポートスペースの必要性は良いマッピング機能を必要とします

アルゴリズム

public void BucketSort(int[] array){
    int max = array[0], min = array[0];
    for(int i = 1; i < array.Length; i ++){
        if(array[i] > max) max = array[i];
        if(array[i] < min) min = array[i];
    }
    List<int>[] buckets = new List<int>[Fun(max, min, array.Length) + 1];
    for(int i = 0; i < buckets.Length; i ++){
        buckets[i] = new List<int>();
    }
    for(int i = 0; i < array.Length; i ++){
        buckets[Fun(array[i], min, array.Length)].Add(array[i]);
    }
    int index = 0;
    for(int i = 0; i < buckets.Length; i ++){
        // 桶内的排序借助了Sort方法,也可以使用其他排序方法
        buckets[i].Sort();
        foreach(int item in buckets[i]){
            array[index ++] = item;
        }
    }
}
// 映射函数,可以根据实际需求选择不同的映射函数
public int Fun(int value, int minValue, int length){
    return (value - minValue) / length;
}

[解説]アルゴリズム

まず、マッピング関数を決定するためにFun、関数の戻り値は添字タブに対応する要素です。そして、列をソートする最大値と最小値を見つけ、バケツの必要数を決定する最大値と最小値によってソートバケット。カラムマッピング関数によってソートとされるすべての要素を横断するFun対応する添え字槽に割り当てます。そしてその後、順次、各バケットのすべての要素をソートするために、C#ソート方法(異なるソート方法の選択)を提供するために使用されます。バレルの要素をソートし、元のシーケンスに戻ってそれらを置くとき。

[について]栗

4、7、1をソートするカラム、16のために、図で使用されてもよい6は、そのバケットソート処理を示します。:

カウンティングソート

基本的な考え方

カウントは、ソートあなたはバケットソートの言葉を理解していれば、ソートカウントすることは比較的非常に簡単です、リアライズの特別なバケットソート考えることができます。
ソート列であるため、カウントすべての要素のシーケンス要件の範囲内にある[0、最大]の正の整数(変形後のコースのすべての要素が正となるように、そのような値を追加することによって陰性であることができます)
基本手順は次のとおりです。

  1. ソートするカラムの最大値を取得し、構築物(最大値+ 1)番目のバレル(最大値+ 1)と考えることができる、配列Cのカウントが、バレルはもはや要素に格納されていないが、各要素が表示されています回数
  2. ソートする列を横切る、カウント配列に現れる各要素の数を数えます。iは、カウントがインクリメントされる場所を発生する要素、すなわち、C [i]は、要素の位置インデックスである++
  3. C [i]が> 0の場合トラバーサル計数アレイは、iが、順次元の配列中に存在する元素に割り当て、要素iが存在することを示し

長所と短所の複雑さと安定性

  • 宇宙複雑:O(k)は
    、ここで説明し、スペースの複雑さのようなものをカウントするため、多くのオンライン記事がマークされているO(N + k)が、実際には、この種およびいくつかのアルゴリズムに関連する特定のアルゴリズムを数えます直接変更するので、空間の複雑さはO(N + K)であると、アルゴリズムがヘルパー配列を使用することなく、本明細書に記載され、元の配列を変更することなく、元のシーケンス補助配列に得られた最終シーケンスカウント配列を追加するので、スペース複雑さはO(K)です。このアルゴリズムは、いくつかの記事を提供し、直接空間計算量はO(n + k)のラベルどんなには誤解読者に非常に簡単、明らかです。
  • 時間計算量:O(N + k)は、kがソートされる列の最大の要素の一定値を表します
  • 好ましくはここで、O(N + K)
  • 最悪の場合:O(N + K)
  • 安定性:安定
  • 利点:安定しており、整数のシーケンスの最大値に適した小型の比較ソートアルゴリズムkの値に基づいており、下限を壊し、非常に大きなではありません
  • 短所:前提条件があり、k値が大きい場合、それは余分なスペースの多くを必要と

アルゴリズム

public void CountSort(int[] array){
    int max = array[0];
    for(int i = 0; i < array.Length; i ++){
        if(array[i] > max) max = array[i];
    }
    int[] count = new int[max + 1];
    for(int i = 0; i < array.Length; i ++){
        count[array[i]] ++;
    }
    int index = 0;
    for(int i = 0; i < count.Length; i ++){
        while(count[i] -- > 0){
            array[index ++] = i;
        }
    }
}

[解説]アルゴリズム

まず、得られた最大値は、列要素がソートされ、アレイ(最大値+1)の長さを構築するためにカウントすることがわかります。ソートされたトラバースする列の各要素、および要素カウント配列の添字によっては、記録要素の出現回数です。目標値に対応する位置が0より大きい場合、トラバース、その要素と被写体の大きさの値がある(いくつかの要素上に発現数に等しい)、配列を数えます。要素は、元の配列に付加されています。目的は、大に小さいことであるので、対応する配列はまた、昇順で得られます。

[について]栗

。カラムは手順を示す1、2、3、4、図5をソートするためにそのカウントをソートするために使用されてもよいです。

基数ソート

基本的な考え方

基数ソート比較するのではなく、「流通」と「コレクト」二つのプロセスによって並べ替え達成するために。
まず、Rキューの確立は0〜R-1、ソートするr個の基数列要素(例えば、小数点、その後= R 10)、その後、割り当てルールコレクション要素に従う列に番号が付けられています。

  1. プレスの最下位ビットの値は、Rのn番目の要素が前記キューに割り当てられ、順次収集キュー内の一般的な要素に、次に小さいです
  2. その後の値は、第2のRの新たに収集した要素の最下位ビットを集め、次いで、キューに割り当てられています
  3. 繰り返し、最上位ビットまで、上述した分布と収集を行うことができます。(ビット数がDである場合、D回繰り返される必要がある、すなわち、ビットの数は、最大数は、次に= 3 D、963であるかのようにすべての要素の最大要素の測定D)

なぜあなたはそれを注文完了することができますか?
大規模に小さい、例えば、割当ておよび割当て解除の最下位に応じて、第1のシーケンスでは、このとき得られたビットは、要素は値の昇順に最下位ビットに基づいています。
時間に応じて、第二の上位ビットを収集分配とは、得られた配列は、最下位ビットの値に従って昇順に、次いで、次の下位ビット要素値に従って昇順である、とします。
最終的な時間分布とコレクションに応じて、最上位ビットは、得られた配列は、要素の最上位ビットの値に従って昇順であるときに、再び次の最上位ビットに応じて配置されています。、再び第二の最下位ビットに応じて、その後、最下位ビットに基づきます。当然、各要素の昇順で完了する。

長所と短所の複雑さと安定性

  • 空間複雑:O(N + R)は、Rは、小数要素として、ベースエレメントを表し、R 10 =
  • 時間計算量:O(D(N + R))
  • 最良の場合:O(D(N + R))
  • 最悪の場合:O(D(N + R))
  • 安定性:安定
  • 長所:安定した、時間の複雑さは、一種のの比較に基づいて下限を突破することができます
  • 短所:追加の補助スペースの必要性

アルゴリズム

public void RadixSort(int[] array){

    int max = GetMaxValue(array);

    int[] buckets = new int[10];
    int[] buffer = new int[array.Length];

    for(int i = 1; max / i > 0; i = i * 10){
        // 统计每个桶中的元素个数
        for(int j = 0; j < array.Length; j ++){
            buckets[array[j] / i % 10] ++;
        }
        // 使每个桶记录的数表示在buffer数组中的位置
        for(int j = 1; j < buckets.Length; j ++){
            buckets[j] += buckets[j - 1];
        }
        // 收集,将桶中的数据收集到buffer数组中
        for(int j = array.Length - 1; j >= 0; j --){
            buffer[-- buckets[array[j] / i % 10]] = array[j];
        }
        for(int j = 0; j < array.Length; j ++){
            array[j] = buffer[j];
        }
        // 清空桶
        for(int j = 0; j < buckets.Length; j ++){
            buckets[j] = 0;
        }
    }
}

// 获得待排序列中的最大元素
public int GetMaxValue(int[] array){
    int max = array[0];
    for(int i = 1; i < array.Length; i ++){
        if(array[i] > max){
            max = array[i];
        }
    }
    return max;
}

[解説]アルゴリズム

R = 10のにアルゴリズムの小数点数であり、
最初の取得が列の最大の要素をソートし、次いで収集し、D倍のビット数が最大要素D割り当てられる
各パス間に分配及び収集を次の
指定されましたこのビットなしの要素は0で表されている場合、中央値は、位置の列でソートされる各要素について計算されます。次いで回数は、それらが現れるバケットアレイ10のレコードの長さを使用して(ここで、タブは対応する要素を記録し、直接使用されません)。次いで横断再びバケットアレイbuckets[j] += buckets[j - 1];の各バケットに記録された値は、指定したビット数で表されているように、補助の配列要素のバケットインデックスに等しいbuffer位置。
順次要素を対応する収集バケットアレイに記録された位置情報に基づいて、収集した後、bufferアレイに。最後にコレクト一度に次の割り当てのために準備し、バケツを空にします。

[について]栗

9、40、123、56、7をソートする列に対して、図17は、図16にその基数ソートの手順を使用してもよい表します。

もっと

上記のアルゴリズムのソースコードはGitHubの上に置かれ、興味のある学生は、クリックすることができますこちらをご覧ください
あなたはGitHubのリポジトリを表示することができ、要約とより多くのコードアルゴリズムの実装(だけでなく、ソートアルゴリズムを)アルゴリズム

おすすめ

転載: www.cnblogs.com/iwiniwin/p/12633644.html