デュアルピボットクイックソートをこれまで見たことがありません。クイックソートのアップグレードエディションの場合
そして、デュアルピボットクイックソートとクイックソートの違いは何ですか?
これはJava doc。
ソートアルゴリズムは、Vladimir Yaroslavskiy、Jon Bentley、およびJoshua Blochによるデュアルピボットクイックソートです。このアルゴリズムは、多くのデータセットでO(n log(n))パフォーマンスを提供し、他のクイックソートを2次のパフォーマンスに低下させます。通常、従来の(1ピボット)クイックソートの実装よりも高速です。
次に、Googleの検索結果でこれを見つけます。クイックソートアルゴリズムのThoery:
- 配列からピボットと呼ばれる要素を選択します。
- ピボットよりも小さいすべての要素がピボットの前になり、ピボットよりも大きいすべての要素がその後になるように配列を並べ替えます(等しい値はどちらの方向にも進むことができます)。この分割後、ピボット要素は最終位置にあります。
- 下位要素のサブ配列と上位要素のサブ配列を再帰的にソートします。
それに比べて、デュアルピボットクイックソート:
()
- 小さな配列(長さ<17)の場合、挿入ソートアルゴリズムを使用します。
- 2つのピボット要素P1およびP2を選択します。たとえば、最初の要素a [left]をP1として、最後の要素a [right]をP2として取得できます。
- P1はP2よりも小さくなければなりません。そうでなければ、スワップされます。そのため、次の部分があります。
- p + 1より小さい要素を持つleft + 1からL–1までのインデックスを持つパートI
- p1以上P2以下の要素を持つLからK–1までのインデックスを持つパートII
- p + 1より大きい要素を持つG + 1からright–1までのインデックスを持つパートIII
- パートIVには、KからGのインデックスで検査される残りの要素が含まれています。
- 部品IVの次の要素a [K]は、2つのピボットP1およびP2と比較され、対応する部品I、II、またはIIIに配置されます。
- ポインターL、K、およびGは、対応する方向に変更されます。
- K≤Gの間、ステップ4〜5が繰り返されます。
- ピボット要素P1はパートIの最後の要素と交換され、ピボット要素P2はパートIIIの最初の要素と交換されます。
- ステップ1〜7は、パートI、パートII、およびパートIIIごとに再帰的に繰り返されます。
興味のある方は、このアルゴリズムをJavaでどのように実装したかをご覧ください。
ソースに記載されているとおり:
「可能であれば、マージのために指定されたワークスペース配列スライスを使用して、配列の指定範囲をソートします
このアルゴリズムは、多くのデータセットでO(n log(n))パフォーマンスを提供します。これにより、他のクイックソートが2次パフォーマンスに低下し、通常、従来の(1ピボット)クイックソート実装よりも高速です。
アルゴリズムの観点から追加したいだけです(つまり、コストは比較とスワップの数のみを考慮します)、2ピボットクイックソートと3ピボットクイックソートは、従来のクイックソート(1ピボットを使用)よりも良くありません。悪い。ただし、最新のコンピューターアーキテクチャの利点を活用するため、実際には高速です。具体的には、キャッシュミスの数が少なくなります。したがって、すべてのキャッシュを削除し、CPUとメインメモリしかない場合、私の理解では、2/3ピボットクイックソートは従来のクイックソートよりも劣ります。
参照:3-pivot Quicksort: https://epubs.siam.org/doi/pdf/10.1137/1.9781611973198.6 従来のQuicksortよりもパフォーマンスが優れている理由の分析: https:/ /arxiv.org/pdf/1412.0193v1.pdf 完全ではなく、あまりにも詳細なリファレンス: https://algs4.cs.princeton.edu/lectures/23Quicksort.pdf