最悪のケース


35

私は最悪の与えるトラブル発見の良いリソース持っています場所での安定したソートアルゴリズムを。誰かが良いリソースを知っていますか?O(nlnn

ただのリマインダーは、渡された配列を使用することを意味し、ソートアルゴリズムは一定の余分なスペースのみを使用できます。安定とは、同じキーを持つ要素が、元の配列と同じ順序でソートされた配列に表示されることを意味します。

たとえば、単純なマージソートは最悪の場合および安定ですが、O n )の余分なスペースを使用します。標準のクイックソートは安定したものにできますが、適切に配置されていますが、最悪の場合はO n 2です。ヒープソートは配置されています。最悪の場合はO n ln n ですが、安定していません。 ウィキペディアには、どのソートアルゴリズムにどの欠点があるかを示す優れたチャートがあります。安定性の3つの条件すべて、最悪の場合O n ln nOnlnnOnOn2Onlnnおよび所定の位置にある。Onlnn

Katajainen、Pasanen、Teuholaによる「Practical in-place mergesort」と呼ばれる論文を見つけました。この論文は、最悪の場合がプレースマージソートバリアントにあると主張しています。結果を正しく理解している場合、配列の最初のと配列の最後ので(ボトムアップ?)mergesortを再帰的に使用し、2番目のをマージするためのスクラッチスペースとして。私はまだこれを読んでいるので、結果を正しく解釈しているかどうかについてのさらなる情報はありがたいです。Onlnn141214

また、安定したクイックソートの最悪のケースにも非常に興味があります。私が理解していることから、クイックソートを最悪のケースO n ln n )に変更するには、通常は安定性を損なう適切なピボット選択する必要があります。OnlnnOnlnn

これは純粋に理論的な関心事であり、私には実用的な応用はありません。これら3つの機能すべてを備えたアルゴリズムを知りたいだけです。


SO上で同様の問題があり、ここで私が質問に設けられた基準を与えるの答えとは。さらなる説明、さらなる文献、そして運が良ければアルゴリズムの説明を求めているので、これは重複した質問ではないと思います。
user834

1
math.stackexchange.comでこの質問を参照してください。
伊藤剛

QuickSortでピボットを選択する別の方法で安定性が損なわれるのはなぜですか?
svick

@ svick、QuickSortを最悪のケースにする方法を知っている唯一の方法は、ランダムよりもインテリジェントにピボットを選択することです。私がそれを学んだ方法は、安定性を破壊する中央値アルゴリズムを使用する選択アルゴリズムを使用することでした。私が何かを逃した場合、私に知らせてください。Onlnn
user834

@TsuyoshiIto、これを答えにすることを検討してください。また、アルゴリズムの簡単なスケッチを提供できれば、それも非常に役立つと思います。
user834

回答:


6

上記のすべてのアルゴリズムがいくつかあり、そのほとんどすべてが過去30年間に発明されました。

おそらく最も良いのは、2008年にKimとKutznerが作成したバージョン(WikiSortと呼ばれる)を含むBlock sortと呼ばれるアルゴリズムのクラスです。また、適応性があるため、ほとんどソートされたリストをソートするための手順が少なくなり、すでにソートされたリストの場合はO(n)比較に収束します。C、C ++、およびJavaの実装については、https//github.com/BonzaiThePenguin/WikiSortをご覧ください。

興味深いのは、Huang and Langston(1989-1992)によるGrailSortアルゴリズム(これもブロックソート)です。これは、いくつかのタイプのテストケースでWikiSortよりも優れています。C ++の実装は、https//github.com/Mrrl/GrailSortから入手できます。


8

インプレースで安定したマージソートを作成できます。詳細はこちらをご覧ください。著者自身の言葉で:

美しい場所-マージアルゴリズム。逆回転配列でテストして、回転がどのように機能するかを理解します。最速の既知のインプレース安定ソート。スタックが爆発する危険はありません。コスト:移動の数が比較的多い。スタックはまだ高価な場合もあります。これは、サブ配列を「回転」させるスマートインプレースマージによるマージソートです。このコードは、C ++ stlライブラリから文字通りコピーされ、Javaに翻訳されます。

ここではコードをコピーしませんが、リンクで見つけるか、C ++ STLを確認してください。ここで何が行われているのかについて、より詳細な説明を提供したい場合はお知らせください。


8
OlnnO1Olnn

KnuthはTAoCPでもこれに対処しています。
ラファエル

Onln2n

1

いくつかの実用的な考えについての長いコメントとしてこれを受け取ってください。これはあなたの質問に対する答えではありませんが、このPythonの議論に興味があるかもしれません。

lgNN1

[...]

長さAとBの隣接するランをインプレースでマージすることは非常に困難です。それを行うことができる理論上の構造は知られていますが、実際の使用には難しすぎて遅すぎます。しかし、min(A、B)に等しい一時メモリがある場合、それは簡単です。

ソース:bugs.python.org、著者:Tim Peters

Onログn

また、ティムソートはすでにソートされたアレイで優れた性能を発揮します。

そのため、PythonはTimsort(いくつかの調整を加えたMergesort)を使用し、数年前にJavaの実装を調べたように、それはMergesortでもありました(現在はTimsortも使用していると思います)。

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