特定のソートアルゴリズムが他よりも優先される場合の使用例は何ですか-マージソートvs QuickSort vsヒープソートvs 'イントロソート'など?
サイズ、データ構造のタイプ、使用可能なメモリとキャッシュ、およびCPUパフォーマンスに基づいてそれらを使用する際の推奨ガイドはありますか?
特定のソートアルゴリズムが他よりも優先される場合の使用例は何ですか-マージソートvs QuickSort vsヒープソートvs 'イントロソート'など?
サイズ、データ構造のタイプ、使用可能なメモリとキャッシュ、およびCPUパフォーマンスに基づいてそれらを使用する際の推奨ガイドはありますか?
回答:
まず、定義が重要です。安定した並べ替えとは、同じキーを持つ要素を並べ替えないことが保証されているものです。
推奨事項:
クイックソート: 安定したソートが必要ない場合、平均的なケースのパフォーマンスは、最悪のケースのパフォーマンスよりも重要です。クイックソートは、平均で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は基数の桁数です。
バケットの並べ替え: 入力がほぼ均一に分散されることが保証できる場合。
通常、クイックソートは平均で最速ですが、かなり厄介な最悪の場合の動作があります。したがって、不良データが提供しないことを保証O(N^2)
する必要がある場合は、それを回避する必要があります。
マージソートは追加のメモリを使用しますが、外部ソート(つまり、メモリに収まらない巨大なファイル)に特に適しています。
ヒープソートはインプレースでソートでき、最悪の場合の2次動作はありませんが、ほとんどの場合、平均でクイックソートよりも低速です。
制限された範囲の整数のみが関係する場合は、ある種の基数ソートを使用して非常に高速にすることができます。
99%のケースでは、通常はクイックソートに基づくライブラリのソートで問題ありません。
並べ替えアルゴリズムに関するウィキペディアのページには、優れた比較表があります。
http://en.wikipedia.org/wiki/Sorting_algorithm#Comparison_of_algorithms
提供されている比較/アニメーションへのリンクで考慮されていないのは、データの量が使用可能なメモリを超えた場合です。それを行う必要がある場合は、通常、マージソートとヒープソートのバリアントを対象とする「外部ソート」を読んでください。
http://corte.si/posts/code/visualisingsorting/index.htmlとhttp://corte.si/posts/code/timsort/index.htmlにも、さまざまな並べ替えアルゴリズムを比較するクールな画像があります。
@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)。(ウィキペディアから)