私は高校時代に多くの分類アルゴリズムに出会いました。ただし、どれが最速かはわかりません(整数のランダム配列の場合)。だから私の質問は:
- 現在知られている最速のソートアルゴリズムはどれですか?
- 理論的には、さらに速いものがある可能性はありますか?それで、ソートの最小の複雑さは何ですか?
私は高校時代に多くの分類アルゴリズムに出会いました。ただし、どれが最速かはわかりません(整数のランダム配列の場合)。だから私の質問は:
回答:
一般的に、挿入ソート、バブルソート、選択ソートなどのソートアルゴリズムがあり、通常は特別な状況でのみ使用する必要があります。クイックソート。最悪の場合はO (n 2)ですが、定数(およびプロパティ)が良好なO (n log n )であり、汎用のソート手順として使用できます。merge-sortやheap-sortなどのO (n log n )アルゴリズム。これも優れた汎用ソートアルゴリズムです。およびO (n、または、基数、バケット、カウントの並べ替えなど、整数のリストの線形並べ替えアルゴリズム。これは、リスト内の整数の性質に応じて適切な場合があります。
リスト内の要素が、要素間の完全な順序関係だけを知っている場合、最適なソートアルゴリズムの複雑度はます。これはかなりクールな結果であり、オンラインで詳細を簡単に見つけることができるはずです。線形並べ替えアルゴリズムは、要素間の完全な順序関係だけでなく、並べ替えられる要素の構造に関する詳細情報を活用します。
さらに一般的には、並べ替えアルゴリズムの最適性は、並べ替えるリストの種類(およびアルゴリズムが実行されるマシンモデルなど)に対して行うことができる仮定に密接に依存します。アルゴリズムが最適です;ストレージ用のテープを備えたマシンでのバブルソートを検討してください)。仮定が強いほど、アルゴリズムでカットできるコーナーが多くなります。リストの「ソート度」をどれだけ効率的に判断できるかという非常に弱い仮定の下では、最適な最悪の複雑さはさえなる可能性があります。
この答えは複雑さだけを扱っています。アルゴリズムの実装の実際の実行時間は、単一の回答で説明するのが難しい多数の要因に依存します。
そのような質問の場合によくあるように、答えは「依存する」です。(a)整数の大きさ、(b)入力配列にランダムな順序またはほぼソートされた順序で整数が含まれているかどうか、(c)ソートアルゴリズムを安定させる必要があるかどうか、 (d)数値のリスト全体がメモリに収まるかどうか(インメモリソートと外部ソート)、および(e)実行するマシン。
実際には、インメモリソートが必要な場合、言語の標準ライブラリのソートアルゴリズムはおそらく非常に優れています(最適に近い)。したがって、実際には、標準ライブラリによって提供される並べ替え関数を使用し、実行時間を測定します。(i)ソートが全体の実行時間の大部分であり、(ii)実行時間が許容できない場合にのみ、ソートアルゴリズムをいじる必要があります。これらの2つの条件が当てはまる場合は、特定のドメインの特定の側面を調べて、他の高速ソートアルゴリズムを試すことができます。
しかし現実的には、実際には、ソートアルゴリズムがパフォーマンスの大きなボトルネックになることはめったにありません。
さらに、2番目の質問に答える
理論的には、さらに速いものがある可能性はありますか?
それで、ソートの最小の複雑さは何ですか?
汎用ソートの場合、比較ベースのソート問題の複雑さはΩ(n log n)です。O(n)で並べ替えを実行するアルゴリズムがいくつかありますが、それらはすべて入力に関する仮定を行うことに依存しており、汎用の並べ替えアルゴリズムではありません。
基本的に、複雑さは、配列の並べ替えに必要な比較の最小数によって与えられます(log nは、配列の各要素を比較するときに構築されるバイナリ決定ツリーの最大の高さを表します)。
ソートの複雑さの下限については、ここで正式な証拠を見つけることができます。
これを書いている時点で他の2つの答えを読みましたが、どちらもあなたの質問に適切に答えたとは思いませんでした。他の答えは、ランダムな分布と空間の複雑さに関する外部の考えを考慮したもので、おそらく高校の研究の範囲外です。だからここに私のテイクがあります。
ハードウェアの制限について言及せず、「最速」を探している場合、利用可能なハードウェアと入力の種類に基づいて、並列ソートアルゴリズムの1つを選択する必要があります。
理論的には、例えばquick_sort
ですO(n log n)
。ではp
、プロセッサ、理想的にこれはに降りてくる必要がありO(n/p log n)
、我々は並行して、それを実行する場合。
ウィキペディアを引用するには:時間の複雑さ...
最適な並列ソートはO(log n)です
実際には、大規模な入力サイズの場合O(log n)
、スケーラビリティの問題のために達成することは不可能です。
これがParallel merge sortの擬似コードです。の実装はmerge()
、通常のマージソートと同じにすることができます。
// Sort elements lo through hi (exclusive) of array A.
algorithm mergesort(A, lo, hi) is
if lo+1 < hi then // Two or more elements.
mid = ⌊(lo + hi) / 2⌋
fork mergesort(A, lo, mid)
mergesort(A, mid, hi)
join
merge(A, lo, mid, hi)
参照: