各並べ替えアルゴリズムはいつ使用されますか?[閉まっている]


170

特定のソートアルゴリズムが他よりも優先される場合の使用例は何ですか-マージソートvs QuickSort vsヒープソートvs 'イントロソート'など?

サイズ、データ構造のタイプ、使用可能なメモリとキャッシュ、およびCPUパフォーマンスに基づいてそれらを使用する際の推奨ガイドはありますか?


データおよびアルゴリズムの異なる種類のアニメーションのセットは、<a href=" sorting-algorithms.com/">で見つけることができsorting-algorithms.com </ A >
チップユニ

2
このようなもののためのbigocheatsheet.comのようなガイドは素晴らしいでしょう
K-SOの毒性が高まっています。

@ChipUniはここに固定リンクがあります:toptal.com/developers/sorting-algorithms
eric

2
なぜこの質問は閉じられているのですか?
Arvand

回答:


316

まず、定義が重要です。安定した並べ替えとは、同じキーを持つ要素を並べ替えないことが保証されているものです。

推奨事項:

クイックソート: 安定したソートが必要ない場合、平均的なケースのパフォーマンスは、最悪のケースのパフォーマンスよりも重要です。クイックソートは、平均でO(N log N)、最悪の場合はO(N ^ 2)です。優れた実装では、再帰のためにスタックスペースの形式でO(log N)補助ストレージを使用します。

マージソート: 安定したO(N log N)ソートが必要な場合、これが唯一のオプションです。唯一の欠点は、O(N)補助スペースを使用し、クイックソートよりも定数がわずかに大きいことです。インプレースマージの並べ替えはいくつかありますが、すべてが安定していないか、O(N log N)よりも劣っています。O(N log N)のインプレースソートでさえ、単純な古いマージソートよりも定数がはるかに大きいため、有用なアルゴリズムよりも理論的な好奇心を持っています。

ヒープソート: 安定したソートが不要で、平均的なケースのパフォーマンスよりもワーストケースのパフォーマンスを重視する場合。これはO(N log N)であることが保証されており、O(1)補助スペースを使用します。つまり、非常に大きな入力でヒープまたはスタックスペースが予期せず不足することはありません。

Introsort: これは、クイックソートのO(N ^ 2)ワーストケースを回避するために、特定の再帰深度の後にヒープソートに切り替わるクイックソートです。O(N log N)のパフォーマンスが保証されたクイックソートの平均的なケースが得られるため、ほとんどの場合、通常のクイックソートよりも優れています。おそらく、これの代わりにヒープソートを使用する唯一の理由は、O(log N)スタックスペースが実質的に重要である、メモリに制約の厳しいシステムにあります。

挿入ソート:クイックソートまたはマージソートのベースケースを含め、Nが小さいことが保証されている場合。これはO(N ^ 2)ですが、定数が非常に小さく、安定したソートです。

バブルソート、セレクションソート:何かをすばやくダーティにしていて、何らかの理由で標準ライブラリのソートアルゴリズムを使用できない場合。これらが挿入ソートよりも優れている唯一の利点は、実装が少し簡単になったことです。


非比較ソート: 一部のかなり限られた条件下では、O(N log N)の障壁を破り、O(N)でソートすることが可能です。これは、試してみる価値があるいくつかのケースです。

ソートのカウント: 範囲が限定された整数をソートする場合。

基数ソート: log(N)がKより大幅に大きい場合。Kは基数の桁数です。

バケットの並べ替え: 入力がほぼ均一に分散されることが保証できる場合。


1
私が覚えているように、ヒープの並べ替えは、同じサイズの異なる入力間でほとんど変動がないという点で非常に予測可能な実行時間を持っていますが、それはその一定の空間境界よりも重要ではありません。また、挿入ソートはn ^ 2ソートを実装するのが最も簡単だと思いますが、それはおそらく私だけです。最後に、シェルソートについても説明します。シェルソートは、挿入ソートと同じくらい簡単に実装できますが、パフォーマンスは向上しますが、n log nではありません。
JaakkoK、2009


2
+1非常に興味深い。「保証...ほぼ均一に分散」する方法を説明していただけますか。バケットソート用?
サムオーバートン

2
なぜイントロソートはクイックソートよりもかなり遅いのですか?唯一のオーバーヘッドは、再帰の深さを数えることですが、無視できます。再帰が適切なクイックソートの場合よりもはるかに深い場合にのみ、スイッチが切り替わります。
dsimcha 2009

2
バブルソートの最良のケースはO(n)であるとは言えません。
Tara

33

通常、クイックソートは平均で最速ですが、かなり厄介な最悪の場合の動作があります。したがって、不良データが提供しないことを保証O(N^2)する必要がある場合は、それを回避する必要があります。

マージソートは追加のメモリを使用しますが、外部ソート(つまり、メモリに収まらない巨大なファイル)に特に適しています。

ヒープソートはインプレースでソートでき、最悪の場合の2次動作はありませんが、ほとんどの場合、平均でクイックソートよりも低速です。

制限された範囲の整数のみが関係する場合は、ある種の基数ソートを使用して非常に高速にすることができます。

99%のケースでは、通常はクイックソートに基づくライブラリのソートで問題ありません。


6
+1:「99%の場合、通常はクイックソートに基づくライブラリのソートで問題ありません。」
ジムG.

ランダムピボットは、悪いデータに関する保証を必要とせずに、Quicksortにすべての実用的な目的でO(nlogn)のランタイムを提供します。私は、誰もがO(n ^ 2)クイックソートを本番コードに実装するとは思いません。
MAK、

2
MAK、たとえば、C標準ライブラリqsortを除いて?(google.com/codesearch/…)-ほとんどの「量産コード」はこれに依存しています
Eli Bendersky

ライブラリのソートは、安定していないため、通常はクイックソートに基づいていません。ほとんどすべての上位言語(Cを想定)は安定したソートを提供します。ほとんどの場合、安定した、または少なくとも決定論的な並べ替えが必要であることはわかっています。
12431234123412341234123 2017


3

提供されている比較/アニメーションへのリンクで考慮されていないのは、データの量が使用可能なメモリを超えた場合です。それを行う必要がある場合は、通常、マージソートとヒープソートのバリアントを対象とする「外部ソート」を読んでください。

http://corte.si/posts/code/visualisingsorting/index.htmlhttp://corte.si/posts/code/timsort/index.htmlにも、さまざまな並べ替えアルゴリズムを比較するクールな画像があります。


0

@dsimchaが書いた:ソートのカウント:範囲が限定された整数をソートする場合

私はそれを次のように変更します:

カウントの並べ替え:正の整数を並べ替える場合(鳩の穴があるため、0-Integer.MAX_VALUE-2)。

線形時間の効率ヒューリスティックとして、常に最大値と最小値を取得することもできます。
また、中間配列には少なくともn個の追加スペースが必要であり、明らかに安定しています。

/**
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

(実際にはMAX_VALUE-2が許可されていますが)参照: Java配列に最大サイズはありますか?

また、基数ソートの複雑さは、ワードサイズwの整数であるn個のキーのO(wn)であることも説明します。ときどきwは定数として表され、基数ソートを(十分に大きなnに対して)最適な比較ベースのソートアルゴリズムよりも優れたものにします。これらはすべてO(n log n)比較を実行してnキーをソートします。ただし、一般にwを定数と見なすことはできません。n個のキーがすべて異なる場合、ランダムアクセスマシンがそれらをメモリに格納できるようにするには、wを少なくともlog nにする必要があります。 (n log n)。(ウィキペディアから)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.