web-dev-qa-db-ja.com

常にヒープソートを使用しないのはなぜですか

ヒープソートソートアルゴリズムはO(nlogn)の最悪の場合の複雑さがあるようで、ソート操作にO(1)スペースを使用します。

これは、ほとんどのソートアルゴリズムよりも優れているようです。それでは、なぜソートアルゴリズムとして常にヒープソートを使用しないのですか(そして、なぜ人々はMergeソートやクイックソートのようなソートメカニズムを使用するのですか)。

また、ヒープソートで「不安定性」という用語を使用する人もいます。それは何を意味しますか?

63
Saket

安定したソートは、同じキーを持つアイテムの相対的な順序を維持します。たとえば、従業員IDと名前を持つレコードがデータセットに含まれているとします。最初の順序は次のとおりです。

_1, Jim
2, George
3, Jim
4, Sally
5, George
_

名前で並べ替えます。安定したソートは、次の順序でアイテムを配置します。

_2, George
5, George
1, Jim
3, Jim
4, Sally
_

「George」の重複レコードは、最初のリストと同じ相対順序になっていることに注意してください。 2つの「Jim」レコードと同じです。

不安定な並べ替えでは、次のようにアイテムを配置できます。

_5, George
2, George
1, Jim
3, Jim
4, Sally
_

ヒープに対する操作は、同じアイテムの相対的な順序を変更する可能性があるため、ヒープソートは安定していません。すべてのQuicksort実装が安定しているわけではありません。パーティショニングの実装方法によって異なります。

HeapsortにはO(n log(n))という最悪の複雑さがありますが、それだけでは話の全体がわかりません。実際の実装では、理論的な分析で考慮されない一定の要因があります。 HeapsortとQuicksortの場合、Quicksortの最悪のケースを実際に非常にまれにする方法(たとえば、中央値5)があることがわかります。また、ヒープの維持は無料ではありません。

正規分布の配列を指定すると、QuicksortとHeapsortは両方ともO(n log(n))で実行されます。ただし、Quicksortの定数係数はHeapsortの定数係数よりも小さいため、Quicksortはより高速に実行されます。簡単に言えば、ヒープを維持するよりもパーティショニングの方が高速です。

112
Jim Mischel

Heap Sortには、O(n log(n))の最悪の複雑さがあります。しかし、経験的な研究によると、一般的にQuick Sort(およびその他のソートアルゴリズム)はヒープソートよりもかなり高速ですが、最悪の場合の複雑さはO(n²)です http://www.cs.auckland.ac.nz/~jmor159/PLDS210/qsort3.html

また、ウィキペディアの クイックソート記事 から:

クイックソートの最も直接的な競争相手はヒープソートです。ヒープソートの最悪の場合の実行時間は常にO(n log n)です。ただし、ヒープソートは、標準のインプレースクイックソートよりも平均してやや遅いと想定されています。これはまだ議論されており、研究中です。いくつかの出版物は反対を示しています。[13] [14] Introsortは、クイックソートの最悪の実行時間を回避するために、不良ケースが検出されたときにヒープソートに切り替えるクイックソートのバリアントです。ヒープソートが必要になることが事前にわかっている場合、それを直接使用する方が、イントロソートがヒープに切り替わるのを待つよりも速くなります。

ただし、応答時間の保証が必要なアプリケーションでは、クイックソートを使用しないでください。

Stackoverflowのソース: Quicksort vs heapsort

9
Jean Logeart

特効薬はありません...

私がまだここで見たことがない別の議論に言及するために:

データセットが非常に大きく、メモリに収まらない場合、マージソートは魅力のように機能します。データセットが数百台のマシンにまたがることができるクラスターで頻繁に使用されます。

6
Karoly Horvath

80年代中頃にタンデムノンストップコンピューターで短期間働いたとき、NlogNのパフォーマンスが保証されているため、システムのコアソートルーチンはHeapSortであることに気付きました。しかし、それを使用する理由がある人は誰も知らないので、実際にどのように機能したかはわかりません。私はヒープソートが好きですが、上記の欠点と同様に、それは現代のメモリをうまく利用していないと言ったと聞いています。なぜなら、それはすべての場所でメモリアクセスを行うためです。一方、クイックソートと小さな基数ソートは比較的少数を混在させることになります順次読み取りおよび書き込みのストリームの-キャッシュがより効果的です。

0
mcdowella

安定したソートアルゴリズムにより、等しいキーを持つレコードの相対的な順序が維持されます

そのような安定性を好むアプリケーションもありますが、ほとんどは気にしません。たとえば、Googleはあなたの友達です。

「Merge sortやQuick sortなどのソートメカニズムを使用している」という主張については、ほとんどの人は言語に組み込まれているものを使用し、ソートアルゴリズムについてはあまり考えていないと思います。自分で転がる人はおそらくヒープの種類について聞いたことがないでしょう(最後は個人的な経験です)。

最後の最大の理由は、すべての人がソートされたヒープを必要とするわけではないということです。ソートされたリストが必要な人もいます。平均的なJoe Programmerの上司が「このリストを並べ替える」と言って、Joeが「これまで聞いたことのないこのヒープデータ構造があります、上司だ!」と言った場合、Joeの次のパフォーマンスレビューはそれほど素晴らしいものではありません。

0
Kane