0.1アルゴリズム分類

0.1アルゴリズム分類

10の一般的な並べ替えアルゴリズムは、次の2つのカテゴリに分類できます。

比較ソート:要素間の相対的な順序は比較によって決定されます。時間の複雑さはO(nlogn)を超えることができないため、非線形時間比較ソートとも呼ばれます。
非比較ソート:要素の相対的な順序は比較によって決定されません。比較ソートに基づいて時間の下限を突破し、線形時間で実行される可能性があるため、線形時間非比較ソートとも呼ばれます。

0.2アルゴリズムの複雑さ

0.3関連する概念

安定:aが元々bの前にあり、a = bの場合、ソート後もaはbの前にあります。
不安定:aが元々bの前にあり、a = bの場合、ソート後にaがbの後ろに表示されることがあります。
時間の複雑さ:ソートされたデータに対する操作の総数。nが変化したときの操作数の法則を反映しています。
スペースの複雑さ:コンピューターでアルゴリズム
を実行するときに必要なストレージスペースの測定値を指します。これは、データサイズnの関数でもあります。

1.バブルソート(バブルソート)

バブルソートは単純なソートアルゴリズムです。ソートするシーケンスに繰り返しアクセスし、一度に2つの要素を比較し、順序が間違っている場合はそれらを交換しました。シーケンスにアクセスする作業は、交換が不要になるまで繰り返されます。これは、シーケンスがソートされたことを意味します。このアルゴリズムの名前の由来は、要素が小さいほど、交換によってシーケンスの先頭にゆっくりと「フロート」するためです。

1.1アルゴリズムの説明

隣接する要素を比較します。
最初のペアが2番目のペアより大きい場合は、2つを交換します。隣接する要素の各ペアに対して、最初の最初のペアから最後の最後のペアまで同じ作業を行い、最後の要素が最大になるようにします。カウント;
最後の要素を除くすべての要素に対して上記の手順を
繰り返します。並べ替えが完了するまで手順1〜3を繰り返します。

1.2アニメーションデモ

1.3コードの実装

functionbubbleSort(arr){ var len = arr.length; for(var i = 0; i <len-1; i ++){ for(var j = 0; j <len-1-i; j ++){ if(arr [j]> arr [j + 1]){//隣接する要素のペアワイズ比較var temp = arr [j + 1]; //要素交換arr [j + 1] = arr [j]; arr [j] = temp; } } } return arr; } 2.選択ソート(Selection-sort)は、シンプルで直感的なソートアルゴリズムです。その動作原理:最初にソートされていないシーケンスで最小(大きい)要素を見つけ、それをソートされたシーケンスの先頭に格納し、次に残りのソートされていない要素から最小(大きい)要素を見つけ続け、次にそれをソートされたシーケンスに入れます最後に。など、すべての要素が並べ替えられるまで続きます。













2.1アルゴリズムの説明
nレコードの直接選択と並べ替えは、n-1回の直接選択と並べ替えによって順序付けられた結果を取得できます。具体的なアルゴリズムは次のとおりです。

初期状態:無秩序な領域はR [1 ... n]で、順序付けられた領域は空です
。i番目の並べ替え(i = 1,2,3 ... n-1)が開始されると、現在の順序付けられた領域と無秩序な領域はそれぞれR [1 ... i-1]およびR(i ... n)。このソートトリップは、現在の無秩序領域から最小のキーを持つレコードR [k]を選択し、それを無秩序領域の最初のレコードRと交換して、R [1 ... i]およびR [i + 1 .. .. n)レコード数が1増加した新しい順序付けされた領域と、レコード数が1つ減少した新しい無秩序領域になります
。n-1パスが終了し、配列が順序付けられます。
2.2動画のデモンストレーション

2.3コード実装
関数selectionSort(arr){ var len = arr.length; var minIndex、temp; for(var i = 0; i <len-1; i ++){ minIndex = i; for(var j = i + 1; j <len; j ++){ if(arr [j] <arr [minIndex]){//最小数を見つけるminIndex = j; //最小数のインデックスを保存する} } temp = arr [i]; arr [i ] = arr [minIndex]; arr [minIndex] = temp; } return arr; } 2.4アルゴリズム分析は、最も安定した並べ替えアルゴリズムの1つです。これは、入力するデータに関係なく、O(n2)時間の複雑さであるため、使用されます。それに関して言えば、データサイズは小さいほど良いです。唯一の利点は、追加のメモリスペースを使用しないことです。理論的には、選択的ソートは、ほとんどの人が考えるソート方法でもあります。
















3.挿入ソート(挿入ソート)
挿入-ソートアルゴリズムの説明は、シンプルで直感的なソートアルゴリズムです。その動作原理は、順序付けられたシーケンスを構築することです。ソートされていないデータの場合、ソートされたシーケンスで後ろから前にスキャンし、対応する位置を見つけて挿入します。

3.1アルゴリズムの説明
一般的に、挿入ソートはインプレースを使用してアレイに実装されます。具体的なアルゴリズムは次のとおりです。

最初の要素から始めて、要素はソートされていると見なすことができます。
次の要素を取り出し、ソートされた要素のシーケンスで前後にスキャンします。
要素(ソート済み)が新しい要素より大きい場合は、要素を一番下に移動します。 1つの位置;
新しい要素以下のソートされた要素の位置が見つかるまで手順3を繰り返します
;新しい要素をその位置に挿入します;
手順2から5を繰り返します。
3.2映画のデモンストレーション

3.2コード実装
関数insertionSort(arr){ var len = arr.length; var preIndex、current; for(var i = 1; i <len; i ++){ preIndex = i-1; current = arr [i]; while( preIndex> = 0 && arr [preIndex]> current){ arr [preIndex + 1] = arr [preIndex]; preIndex–; } arr [preIndex + 1] = current; } return arr; } 3.4実装におけるアルゴリズム分析と挿入ソート上記では、通常、インプレースソート(つまり、O(1)の余分なスペースのみが必要なソート)が使用されるため、前後にスキャンするプロセスでは、ソートされた要素を最新の要素に繰り返しシフトする必要があります。挿入スペースを提供します。














4.シェルソート(シェルソート)
1959年に発明された最初の画期的なO(n2)ソートアルゴリズムであるシェルは、単純な挿入ソートの改良版です。挿入ソートとの違いは、最初に遠い要素を比較することです。ヒルソーティングは、縮小インクリメンタルソーティングとも呼ばれます。

4.1アルゴリズムの説明
最初に、直接挿入ソートのために、ソートされるレコードのシーケンス全体をいくつかのサブシーケンスに分割します。特定のアルゴリズムの説明は次のとおりです。

インクリメンタルシーケンスt1、t2、...、tkを選択します。ここで、ti> tj、tk = 1です。
インクリメンタルシーケンスの数kに従って、シーケンスはk回ソートされます。
各パスは、対応する増分tiに従ってソートされ、待機します。ソートシーケンスは、長さmのいくつかのサブシーケンスに分割され、各サブテーブルが直接挿入されてソートされます。増分係数が1の場合のみ、シーケンス全体がテーブルとして扱われ、テーブルの長さはシーケンス全体の長さになります。
4.2アニメーションデモ

4.3コード実装
関数shellSort(arr){ var len = arr.length; for(var gap = Math.floor(len / 2); gap> 0; gap = Math.floor(gap / 2)){ //注:これは、アニメーションのデモンストレーションとは異なります。アニメーションはグループで実行されます。実際の操作では、(var i = gap; i <len; i ++){ var j = i; var current = arr [i];に対して複数のグループが交互実行されます。while(j-gap> = 0 && current <arr [j-gap]){ arr [j] = arr [j-gap]; j = j-gap; } arr [j] = current; } } return arr; } 4.4アルゴリズム分析ヒルソーティングの中核は、インターバルシーケンスの設定にあります。インターバルシーケンスは事前に設定することも、インターバルシーケンスを動的に定義することもできます。インターバルシーケンスを動的に定義するためのアルゴリズムは、「Algorithm(4thEdition)」の共著者であるRobertSedgewickによって提案されました。
















5.マージソート(マージソート)マージソート
は、マージ操作に基づく効果的なソートアルゴリズムです。このアルゴリズムは、Divide andConquerの非常に典型的なアプリケーションです。既存の順序付けられたサブシーケンスを組み合わせて、完全に順序付けられたシーケンスを取得します。つまり、最初に各サブシーケンスを順番に作成し、次にサブシーケンスを順番に作成します。2つの順序付きリストが1つの順序付きリストにマージされる場合、それは双方向マージと呼ばれます。

5.1アルゴリズムの説明
長さnの入力シーケンスを長さn / 2の2つのサブシーケンスに分割し、
これら2つのサブシーケンスでそれぞれマージソートを使用します
。2つのソートされたサブシーケンスをマージして最終的なソートシーケンスにします。
5.2映画のデモンストレーション

5.3代码コード
関数mergeSort(arr){ var len = arr.length; if(len <2){ return arr; } var middle = Math.floor(len / 2)、left = arr.slice(0、middle)、right = arr.slice(middle); merge(mergeSort(left)、mergeSort(right));を返します。}








関数merge(左、右){ var result = [];

while (left.length>0 && right.length>0) {
    if (left[0] <= right[0]) {
        result.push(left.shift());
    } else {
        result.push(right.shift());
    }
}

while (left.length)
    result.push(left.shift());

while (right.length)
    result.push(right.shift());

return result;

}
5.4アルゴリズム分析
マージソートは、安定したソート方法です。選択ソートと同様に、マージソートのパフォーマンスは入力データの影響を受けませんが、常にO(nlogn)時間の複雑さであるため、選択ソートよりもはるかに優れたパフォーマンスを発揮します。価格は、追加のメモリスペースの必要性です。

6.クイックソート
の基本的な考え方:ソートによって、ソートされるレコードを2つの独立した部分に分割し、レコードの一方の部分のキーワードは、もう一方の部分のキーワードよりも小さくなります。一部のレコードは、シーケンス全体の順序を達成するために引き続きソートされます。

6.1アルゴリズムの説明
クイックソートでは、divideとconquerを使用して、文字列(リスト)を2つのサブリスト(サブリスト)に分割します。具体的なアルゴリズムは次のとおりです。

シーケンスから要素を選択し、それを「ピボット」と呼びます。
参照値よりも小さいすべての要素が参照の前に配置され、参照値よりも大きいすべての要素が参照(同じ番号)の後ろに配置されるように、シーケンスを並べ替えます。あなたはどちらの側にも行くことができます)。パーティションが終了した後、ベンチマークはシーケンスの途中にあります。これはパーティション操作と呼ばれ
、参照値よりも小さい要素のサブ配列と、参照値よりも大きい要素のサブ配列を再帰的にソートします。
6.2映画のデモンストレーション

6.3代码コード
関数quickSort(arr、left、right){ var len = arr.length、partitionIndex、left = typeof left!= 'number'?0:左、右= typeof right!= 'number'?len-1:右;



if (left < right) {
    partitionIndex = partition(arr, left, right);
    quickSort(arr, left, partitionIndex-1);
    quickSort(arr, partitionIndex+1, right);
}
return arr;

}

function partition(arr、left、right){//分区操作
varピボット=左、//設定基統合值(ピボット)
インデックス=ピボット+ 1;
for(var i = index; i <= right; i ++){ if(arr [i] <arr [pivot]){ swap(arr、i、index); index ++; } } swap(arr、pivot、index-1); インデックス-1を返します。}







function swap(arr、i、j){ var temp = arr [i]; arr [i] = arr [j]; arr [j] = temp; } 7.ヒープソート(ヒープソート)はいヒープデータ構造を使用して設計されたソートアルゴリズムを指します。スタッキングは、完全なバイナリツリーを近似する構造であり、スタッキングの性質も満たします。つまり、子ノードのキーまたはインデックスは、常にその親ノードよりも小さい(または大きい)です。





7.1アルゴリズムの説明
ソートするキーワードの初期シーケンス(R1、R2 ... Rn)を、最初の無秩序な領域である大きなトップヒープに構築し
、トップ要素R [1]を最後の要素R [n]と交換します。この場合、新たな無秩序領域(R1、R2、... RN-得るために1) R [1,2 ... N-1]を満足し、新しい順序付き領域(のRnのを) ; <= R [N]
以来交換後、ヒープの新しい上部R [1]はヒープの性質に違反する可能性があるため、現在の無秩序領域(R1、R2、... Rn-1)を新しいヒープに調整してから、R [1]と無秩序領域を再度調整する必要があります。最後の要素が交換され、新しい無秩序領域(R1、R2 ... Rn-2)と新しい秩序領域(Rn-1、Rn)が取得されます。このプロセスは、順序付けされた領域の要素数がn-1になるまで繰り返され、ソートプロセス全体が完了します。
7.2アニメーションデモ

7.3コードの実装
varlen; //宣言された複数の関数にはデータ長が必要なため、lenをグローバル変数として設定します

function buildMaxHeap(arr){//建立大顶極
len = arr.length;
for(var i = Math.floor(len / 2); i> = 0; i –){ heapify(arr、i); } }


function heapify(arr、i){//右调整
var左= 2 * i + 1、
右= 2 * i + 2、
最大= i;

if (left < len && arr[left] > arr[largest]) {
    largest = left;
}

if (right < len && arr[right] > arr[largest]) {
    largest = right;
}

if (largest != i) {
    swap(arr, i, largest);
    heapify(arr, largest);
}

}

関数swap(arr、i、j){ var temp = arr [i]; arr [i] = arr [j]; arr [j] = temp; }



関数heapSort(arr){ buildMaxHeap(arr);

for (var i = arr.length - 1; i > 0; i--) {
    swap(arr, 0, i);
    len--;
    heapify(arr, 0);
}
return arr;

}
8.カウントソート
は、比較に基づくソートアルゴリズムではありません。そのコアは、入力データ値をキーに変換し、それらを追加の配列スペースに格納することです。一種の線形時間の複雑さとして、カウントソートでは、入力データが特定の範囲の整数である必要があります。

8.1アルゴリズムの説明
ソートする配列内の最大要素と最小要素を見つけます。
配列内の値iで各要素の出現回数をカウントし、それを配列Cのi番目の項目に格納します。
すべてのカウントを累積します(Cの最初から)要素から始めて、各項目を前の項目に追加します);
ターゲット配列を逆方向に塗りつぶします:各要素iを新しい配列のC(i)項目に配置し、要素を配置するたびにC(i)を減算します1に移動します。
8.2映画のデモンストレーション

8.3代码コード
関数countingSort(arr、maxValue){ varbucket = new Array(maxValue + 1)、sortedIndex = 0; arrLen = arr.length、bucketLen = maxValue + 1;



for (var i = 0; i < arrLen; i++) {
    if (!bucket[arr[i]]) {
        bucket[arr[i]] = 0;
    }
    bucket[arr[i]]++;
}

for (var j = 0; j < bucketLen; j++) {
    while(bucket[j] > 0) {
        arr[sortedIndex++] = j;
        bucket[j]--;
    }
}

return arr;

}
8.4アルゴリズム分析
カウントソートは、安定したソートアルゴリズムです。入力要素が0からkまでのn個の整数の場合、時間の複雑さはO(n + k)であり、空間の複雑さもO(n + k)であり、その並べ替え速度はどの比較並べ替えアルゴリズムよりも高速です。kがそれほど大きくなく、シーケンスが比較的集中している場合、カウントソートは非常に効果的なソートアルゴリズムです。

9.バケットソート
は、カウントソートのアップグレードバージョンです。関数のマッピング関係を使用し、効率の鍵はマッピング関数の決定にあります。バケットソートの動作原理:入力データが均一に分散されていると仮定すると、データは限られた数のバケットに分割され、各バケットは個別にソートされます(別のソートアルゴリズムを使用することも、再帰的に使用し続けることもできます)。バケットソートが実行されます)。

9.1アルゴリズムの説明
量的配列を空のバケットとして設定
し、入力データをトラバースし、データを1つずつ対応するバケットに配置します。空でない
各バケットを並べ替えます。
空でないバケットを並べ替えないでくださいデータは一緒に接合されます。
9.2画像のデモンストレーション

9.3代码コード
関数bucketSort(arr、bucketSize){ if(arr.length === 0){ return arr; }


var i;
var minValue = arr[0];
var maxValue = arr[0];
for (i = 1; i < arr.length; i++) {
  if (arr[i] < minValue) {
      minValue = arr[i];                // 输入数据的最小值
  } else if (arr[i] > maxValue) {
      maxValue = arr[i];                // 输入数据的最大值
  }
}

// 桶的初始化
var DEFAULT_BUCKET_SIZE = 5;            // 设置桶的默认数量为5
bucketSize = bucketSize || DEFAULT_BUCKET_SIZE;
var bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1;  
var buckets = new Array(bucketCount);
for (i = 0; i < buckets.length; i++) {
    buckets[i] = [];
}

// 利用映射函数将数据分配到各个桶中
for (i = 0; i < arr.length; i++) {
    buckets[Math.floor((arr[i] - minValue) / bucketSize)].push(arr[i]);
}

arr.length = 0;
for (i = 0; i < buckets.length; i++) {
    insertionSort(buckets[i]);                      // 对每个桶进行排序,这里使用了插入排序
    for (var j = 0; j < buckets[i].length; j++) {
        arr.push(buckets[i][j]);                     
    }
}

return arr;

}
9.4アルゴリズム分析
バケットソートは線形時間O(n)で最もよく使用されます。バケットソートの時間の複雑さは、他の部分の時間の複雑さがOであるため、各バケット間のデータのソートの時間の複雑さに依存します。 (n)。明らかに、分割されるバケットが小さいほど、各バケット間のデータが少なくなり、並べ替えにかかる時間が短くなります。ただし、対応するスペース消費量は増加します。

10. Radix Sort(Radix Sort)
Radixソートは、下位順にソートされてから収集され、次に上位にソートされてから収集され、以下同様に最高位までソートされます。一部の属性には優先順位があり、最初に低優先度で並べ替えてから、高優先度で並べ替える場合があります。最後の順序は、高い優先度が最初であり、同じ高い優先度を持つ低い優先度が最初です。

10.1アルゴリズムの説明
配列内の最大数を取得し、桁数を取得します;
arrは元の配列であり、各ビットは最下位ビットから取得されて基数配列を形成します;
基数はカウントおよびソートされます(小さな範囲番号のカウントソートの特性を使用);
10.2映画のデモ

10.3代码コードvarcounter
= [];
関数radixSort(arr、maxDigit){ var mod = 10; var dev = 1; for(var i = 0; i <maxDigit; i ++、dev * = 10、mod = 10){ for(var j = 0; j <arr.length; j ++){varbucket = parseInt((arr [j]% mod)/ dev); if(counter [bucket] == null){ counter [bucket] = []; } counter [bucket] .push(arr [j]); } var pos = 0; for(var j = 0; j <counter.length; j ++){ var value = null; if(counter [j]!= null){ while((value = counter [j] .shift())!= null){ arr [pos ++] = value; } } } } return arr;





















}
10.4アルゴリズム分析
カーディナリティソートは、個別のソートと個別の収集に基づいているため、安定しています。ただし、基数ソートのパフォーマンスはバケットソートのパフォーマンスよりもわずかに劣ります。キーの各バケット割り当てにはO(n)時間の複雑さが必要であり、割り当て後に新しいキーシーケンスを取得するにはO(n)時間の複雑さが必要です。ソートするデータをd個のキーワードに分割できる場合、基数ソートの時間の複雑さはO(d
2n)になります。もちろん、dはnよりはるかに小さいため、基本的に線形です。

基数ソートのスペースの複雑さはO(n + k)です。ここで、kはバケットの数です。一般的に言えば、n >> kなので、余分なスペースには約nが必要です。

おすすめ

転載: blog.csdn.net/GodfatherTye/article/details/109123061