なぜクイックソートはマージソートよりも優れているのでしょうか?
ウィキペディアのクイックソート を参照してください:
通常、クイックソートは実際には他のΘ(nlogn)アルゴリズムよりもはるかに高速です。これは、その内部ループをほとんどのアーキテクチャで効率的に実装できるためです。時間。
非常に低いメモリ要件も大きなプラスであることに注意してください。
通常、クイックソートは、データがメモリに格納されている場合、マージソートよりも高速です。ただし、データセットが巨大で、ハードドライブなどの外部デバイスに格納されている場合、マージソートが速度の面で明確な勝者です。外部ドライブの高価な読み取りを最小限に抑え、並列計算にも適しています。
個人的には、クイックソートとマージソートの違いを自分でテストしたいと思い、1,000,000要素のサンプルの実行時間を見ました。
クイックソートは156ミリ秒で実行できました 一方、 マージソートは247ミリ秒で実行しました
ただし、クイックソートデータはランダムであり、データがランダムであればクイックソートはうまく機能します。マージソートの場合とは異なり、マージソートはデータがソートされるかどうかに関係なく同じように実行されます。ただし、マージソートには1つの完全な追加スペースが必要で、クイックソートはインプレースソートではありません。
私も彼らのための包括的な作業プログラムを書きました。
多くの場合、クイックソートがマージソートよりも優れた選択肢ですが、マージソートが論理的に優れた選択肢である場合があります。最も明らかなのは、アルゴリズムがO(n ^ 2)よりも速く実行されることが非常に重要な場合です。クイックソートは通常これよりも高速ですが、理論的に考えられる最悪の入力を考えると、O(n ^ 2)で実行される可能性があり、これは最悪のマージソートよりも悪いです。
また、クイックソートはマージソートよりも複雑です。特に、非常に堅実な実装を作成する場合は、したがって、シンプルさと保守性を目指している場合、マージソートはパフォーマンスの低下がほとんどない有望な代替手段になります。
クイックソートが配置されています。パーティショニング機能中にデータの位置を交換するだけです。 Mergesortでは、さらに多くのデータのコピーが必要です。 Merge関数用に別の一時ストレージ(通常は元のデータ配列と同じサイズ)が必要です。
他に加えて:マージソートは、リンクリストのような不変のデータ構造に対して非常に効率的であるため、(純粋に)関数型プログラミング言語に適しています。
実装が不十分なクイックソートは、 セキュリティリスク になります。
クイックソートは、理由によりそう呼ばれます
ハイライト:両方とも安定したソートであるため(単に実装に迷惑をかける)
こいつが「乱用」されているという大げさな表記法と非常に混同されており、両方とも0(nlogn)の平均的なケースの複雑さを持っています。
しかし、マージソートは常に0(nlogn)であるのに対し、不良パーティション、つまり1要素-10要素(ソートリストまたは逆ソートリストにより発生する可能性がある)のようなスキューパーティションのクイックソートは0(n ^ 2)..
..したがって、ランダムなクイックソートがあり、ピボットをランダムに選択し、そのような歪んだパーティション化を回避し、3-4のような適度に歪んだパーティション化であってもn ^ 2シナリオ全体を無効にします。nlog(7/4)n 、理想的には1-1分割、つまりO(nlog(2)n)の2分割が必要です。
したがって、それはO(nlogn)であり、ほとんどの場合、マージソートとは異なり、「big-oh」表記の下に隠された定数は、マージソートよりもクイックソートの方が優れており、マージソートのような余分なスペースを使いません。
ただし、クイックソートを完全に実行するには、微調整、言い換え、クイックソートが必要です。
答えは、プリミティブ値のDualPivotQuickSortでもたらされた変更に対するクイックソートw.r.tに向かってわずかに傾くでしょう。 Java 7で使用してJava.util.Arraysでソートします
It is proved that for the Dual-Pivot Quicksort the average number of
comparisons is 2*n*ln(n), the average number of swaps is 0.8*n*ln(n),
whereas classical Quicksort algorithm has 2*n*ln(n) and 1*n*ln(n)
respectively. Full mathematical proof see in attached proof.txt
and proof_add.txt files. Theoretical results are also confirmed
by experimental counting of the operations.
Java7の実装はここにあります- http://grepcode.com/file/repository.grepcode.com/Java/root/jdk/openjdk/7-b147/Java/util/Arrays.Java
DualPivotQuickSortのさらに素晴らしい読書- http://permalink.gmane.org/gmane.comp.Java.openjdk.core-libs.devel/2628
クイックソートの方が優れているとは限りません。また、それはあなたが意味するもの、メモリ消費、または速度に依存します。
メモリ消費に関しては、最悪の場合、クイックソートはn ^ 2メモリを使用できます(つまり、各パーティションは1〜n-1です)が、マージソートはnlognを使用します。
上記は速度の点で従います。
クイックソートが配置されています。追加メモリはほとんど必要ありません。これは非常に重要です。
中央値の適切な選択により、さらに効率的になりますが、中央値の不適切な選択でもシータ(nlogn)が保証されます。