ソートアルゴリズムの安定性とは何ですか。なぜそれが重要なのですか。


292

私は非常に好奇心旺盛ですが、なぜソートアルゴリズムでは安定性が重要であるか重要ではないのですか?


2
並列化のために?例:マージソートは安定しており、並列化がうまくいくため、クイックソートも同様です。
DarthVader

13
クラシックQuickSortが不安定
Konstantin Spirin '05 / 10/05

9
安定したソートアルゴ-– IBM (Insertion, Bubble, Merge)
roottraveller

私のような概念を誤解しているかもしれない人への注意:等しい要素の順序は保持されることが保証されています。つまり、安定したソートの要素が等しいと見なされた場合、それらは前の順序に従います。 それは私が以前考えていたものではありません。前の順序の要素が等しいと見なされた場合、次の安定したソートでは、それらは前の順序に従います。後者の理解は多くの場合に意味をなすかもしれませんが。
リック

回答:


371

並べ替えアルゴリズムは、キーが等しい2つのオブジェクトが、並べ替えられる入力配列に表示されるのと同じ順序で並べ替えられた出力に表示される場合、安定していると言います。挿入ソート、マージソート、バブルソートなど、一部のソートアルゴリズムは本質的に安定しています。ヒープソート、クイックソートなど、一部のソートアルゴリズムは安定していません。

背景:「安定した」ソートアルゴリズムは、同じソートキーを持つアイテムを順番に保持します。5文字の単語のリストがあるとします。

peach
straw
apple
spork

各単語の最初の文字だけでリストを並べ替えると、安定した並べ替えは次のようになります。

apple
peach
straw
spork

不安定なソートアルゴリズム、strawまたはspork交換することができるが、(以降、安定なの一つに、それらが同じ相対位置にとどまるstraw前に表示されるspork入力で、それはまた、前に表示されるspork出力で)。

このアルゴリズムを使用して単語のリストを並べ替えることができます。5列目、4列目、3列目、2列目、1列の順に並べ替えます。最後に、正しく並べ替えられます。それを納得してください。(ちなみに、そのアルゴリズムは基数ソートと呼ばれています)

次に、質問に答えるために、姓名のリストがあるとします。「姓、次に名順」でソートするように求められます。最初にファーストネームで(安定または不安定)ソートし、次にラストネームで安定ソートすることができます。これらのソート後、リストは主に姓でソートされます。ただし、姓が同じ場合は、名がソートされます。

不安定なソートを同じ方法でスタックすることはできません。


では、リンゴピーチスポーツストローの正しい並べ替え順序で単語を作成するために、どのような並べ替えを呼び出すのでしょうか。究極の正しいソートがリンゴ桃のスポーツわらなければなりませんので、stは、SP(アルファベット順正解)した後でなければなりませんしかし、安定したソートは、私たちにリンゴ桃のわら先割れスプーンを与えた
user1416486

2
@ user1416486:最初の文字のみで並べ替えています。その仮定でstrawspork等しいと比較してください。安定したソートは入力の順序を保持しますが、不安定なソートはその保証をしません。「正しい」は、アプリケーションによって異なります。ほとんどのプログラミング言語の並べ替え関数では、ユーザーがカスタムの順序付け関数を指定できます。ユーザーの関数が異なる項目を同じものとして扱う場合(たとえば、同じ姓、異なる姓)、元の順序が保持されるかどうかを知るのに役立ちます。実際の例については、OCamlの配列ソート関数を参照してください。
ジョーイアダムス

3
行が分からない..同じソートキー?ここのキーはどういう意味ですか?声明を説明してください..同じソートキー
saplingPro

2
@saplingPro:「ソートキー」とは、アイテムをソートすることを意味します。したがって、最初の文字で並べ替えると、各アイテムの「並べ替えキー」が最初の文字になります。
ジョーイアダムス

12
例-フライトの目的地と出発時刻に関する情報を持つ各項目のリストがあるとします。最初に、時間に基づいてリストを並べ替えます。次に、宛先に基づいてソートします。2番目の種類が安定している場合、すべてのフライトが同じ目的地に一緒にバインドされ、出発時刻の昇順になります。安定していなければ、時間の昇順ではありません。
roottraveller 2017

55

安定したソートアルゴリズムは、入力に現れるのと同じ順序で同じ要素をソートするアルゴリズムですが、不安定なソートケースを満たさない場合があります。- 私はアルゴリズムの講師であるDidem Gozupekにアルゴリズムへの洞察を提供してくれたことに感謝します

安定した並べ替えアルゴリズム:

  • 挿入ソート
  • マージソート
  • バブルソート
  • ティム・ソート
  • カウントソート
  • ブロックソート
  • Quadsort
  • ライブラリの並べ替え
  • カクテルシェーカーソート
  • Gnome Sort
  • 奇数-偶数ソート

不安定な並べ替えアルゴリズム:

  • ヒープソート
  • 選択ソート
  • シェルソート
  • クイックソート
  • イントロソート(クイックソートの対象)
  • ツリーソート
  • 循環ソート
  • スムーズソート
  • トーナメントソート(ヘサソートの対象)

ここに画像の説明を入力してください


2
あなたの値は等しくありません。あなたは9,7と9,8を比較しますが、安定性チェックによると、両方が9,7または両方が9,8のように同じ値が必要です。また、安定したアルゴリズムでは、同じ値を同じ順序で並べる必要があります。
erhun

1
いいえ、安定性を確認するには、値が同じである必要があります。つまり、2つの9,7を使用し、ノードAとノードBに名前を付けるとします。すべての並べ替え操作の順序が(等しいではなく)A、Bである場合、並べ替えアルゴリズムが安定している(マージソートのように)ことを理解してください。複数回ソートしたときにA、Bの順序が変わる場合(1. A、BをソートしてからB、Aを再度A、Bなどにソートする)、ソートアルゴリズムが不安定であることを理解する(クイックソートのように)@snr
erhun

@snr [9、6]は入力配列に存在しません。私はあなたが最後の配列ストリップで[9、8]を意味したと思います。
Usman 2017年

4
@erhun私は彼が最初の番号(カンマの前に1)によってのみソートし、あなたが最初の9秒9と異なることを確認するためだけの基準として二番目の数字を使用していると考えている
ティアゴ

20

ソートの安定性とは、同じキーを持つレコードがソート前後の相対的な順序を保持することを意味します。

したがって、解決している問題がその相対的な順序の保持を必要とする場合にのみ、安定性が重要です。

安定性が必要ない場合は、ヒープソートやクイックソートなど、ライブラリの高速メモリアルゴリズムを使用して、それを忘れることができます。

安定性が必要な場合は、さらに複雑です。安定したアルゴリズムは、不安定なアルゴリズムよりもbig-O CPUやメモリの使用率が高くなります。したがって、大きなデータセットがある場合は、CPUとメモリのどちらを破壊するかを選択する必要があります。CPUとメモリの両方に制約がある場合は、問題があります。優れた妥協安定アルゴリズムは、バイナリツリーソートです。Wikipediaの記事は、 STLに基づいて哀れ簡単にC ++の実装を持っています。

各レコードの最後のキーとして元のレコード番号を追加することにより、不安定なアルゴリズムを安定したものにすることができます。


1
Merge Sortのような安定したアルゴリズムは、Quicksortと同じO(NlogN)の複雑さを持っています。ただし、努力の定数乗数は大きくなります。
ジョナサンレフラー、

はい、マージソートでのメモリ使用量はO(N)ですが、クイックソートではO(log N)です。Quicksortについて言及した理由は、qsort()がC標準ライブラリルーチンであるため、いつでも利用できるためです。
ボブマーフィー、

1
全体的な最良の答えは私見です。他で言及されているマルチキー技術は興味深いですが過大評価されています。適用は簡単ですが、明白な代替案よりもはるかに遅くなる傾向があります(マルチキー比較で1つのソートを使用するか、最初のキーでソートしてから、重複するサブリストを識別してソートします)。一部のアプリでは、安定したソートが予測可能な結果を​​生成するという事実が重要になる場合があります。特に、リストBに追加のエントリがあることを除いて同一である2つの入力リストA、Bがある場合、Bに同じ追加のエントリがあることを除いて、安定ソートの出力は同じになります。そして最後のpgphの+1。
greggo 2013

16

それはあなたが何をするかに依存します。

姓と名のフィールドを持つレコードが何人かあるとします。まず、リストを名でソートします。次に、安定したアルゴリズムでリストを姓で並べ替えると、名と姓で並べ替えられたリストができます。


4
私はあなたが「姓と名」を意味すると思います。通常、姓は姓です。
ベーコンビット

14

安定性が重要になる理由はいくつかあります。1つは、2つのレコードを交換することによって交換する必要がない場合、メモリ更新を引き起こす可能性があり、ページがダーティとマークされ、ディスク(または別の低速なメディア)に再書き込みする必要があることです。


レコードのスワッピングは安定性とどのように関係していますか?
user1683793

4

並べ替えアルゴリズムは、等しいキーを持つ2つのオブジェクトが、並べ替えられた出力で、並べ替えられていない入力配列に表示されるのと同じ順序で表示される場合、安定していると言います。挿入ソート、マージソート、バブルソートなど、一部のソートアルゴリズムは本質的に安定しています。ヒープソート、クイックソートなど、一部のソートアルゴリズムは安定していません。

ただし、安定していない任意の特定のソーティングアルゴは、安定するように変更できます。ソートアルゴ固有の方法で安定させることができますが、一般に、本質的に安定していない比較ベースのソートアルゴリズムは、2つのキーの比較で位置が等しいキーを持つオブジェクトの係数。

参照:http : //www.math.uic.edu/~leon/cs-mcs401-s08/handouts/stability.pdf http://en.wikipedia.org/wiki/Sorting_algorithm#Stability


3

これには多くの答えがあることは知っていますが、私にとっては、この答えRobert Harveyにより、より明確に要約されています。

安定したソートとは、入力セットの元の順序を維持するソートであり、[unstable]アルゴリズムは2つ以上のアイテムを区別しません。

ソース


1

並べ替える対象が単なる数値であり、それらの値のみがそれらを識別/識別している(たとえば、同じ値を持つ要素は同一である)と仮定すると、並べ替えの安定性の問題は意味がありません。

ただし、並べ替えの優先順位が同じオブジェクトは異なる場合があり、それらの相対的な順序が意味のある情報になる場合があります。この場合、ソートが不安定になると問題が発生します。

たとえば、ゲーム内のレベル[L]の迷路を掃除するためにすべてのプレーヤーの時間コスト[T]を含むデータのリストがあるとします。迷路を掃除する速さでプレイヤーをランク付けする必要があるとします。ただし、追加のルールが適用されます。時間のコストがどれだけ長くても、より高いレベルで迷路を掃除するプレイヤーは常により高いランクになります。

もちろん、ルールに従ったアルゴリズムを使用してペア値[T、L]を実数[R]にマッピングし、[R]値ですべてのプレーヤーをランク付けすることもできます。

ただし、安定した並べ替えが可能な場合は、リスト全体を[T](最初に速いプレイヤー)で並べ替え、次に[L]で並べ替えることができます。この場合、プレイヤーをクリーンアップした迷路のレベルでグループ化した後、(時間コストによる)プレイヤーの相対的な順序は変更されません。

PS:もちろん、2回並べ替えるアプローチは特定の問題に対する最善の解決策ではありませんが、投稿者の質問を説明するにはそれで十分です。


0

安定したソートは、常に同じ入力で同じ解(順列)を返します。

たとえば、[2,1,2]は順列[2,1,3]として安定したソートを使用してソートされます(最初はインデックス2、次にインデックス1、次にソートされた出力のインデックス3)つまり、出力は常に同じ方法でシャッフルされます。その他の非安定ですが、まだ正しい順列は[2,3,1]です。

クイックソートは安定したソートではなく、同じ要素間の置換の違いはピボットを選択するアルゴリズムに依存します。一部の実装はランダムに取得し、同じアルゴリズムを使用して同じ入力で異なる並べ替えをすばやくソートすることができます。

安定したソートアルゴリズムは決定論的に必要です。


2
それは安定性が意味するものではありません。参照en.wikipedia.org/wiki/Sorting_algorithm#Stability
ルイス・オリヴェイラ

非安定ソートが同じ実装間でも異なるソリューションを出力する可能性があるため、最後の文を修正する必要があります。安定したソートは同じソリューションを出力します。
Luka Rahne、2013年

1
なぜ-1?誰かがここで何が間違っているかを喜ばせることができますか?これは、安定ソートが何であるかではなく、安定ソートが持つ特性です。
Luka Rahne、2016年

ソートが確定的であるかどうかは、それが安定しているかどうかを決定しません。異なるタイブレイク動作を定義することにより(たとえば、非キーパーツをサブソートすることにより)、不安定で確定的なソートアルゴリズムを作成できます。安定したソートは、タイがソートされるときに、要素の事前にソートされた相対的な順序が保持されることを特に意味します。安定したソートの出力例:sort([(5,3),(1,5),(3,3),(1,3)], x) => [(1,5),(1,3),(3,3),(5,3)]。常に(確定的に)出力する確定的なソートを作成できます[(1,3),(1,5),(3,3),(5,3)]が、これは安定したソートではありません。
2017年

@cowbertすべての安定した並べ替えが持つ素晴らしいプロパティについてのより多くのステートメントです。これは、魔女の安定したソートアルゴリズムまたは実装が使用されているかどうかに関係なく、毎回同じ結果になります。異なる非安定ソート実装間でこのようなプロパティを維持することは困難です。
Luka Rahne、2017年

0

安定したソートが必要な理由のいくつかの例。データベースは一般的な例です。取引データベースの場合は、姓、名、購入日時、アイテム番号、価格が含まれます。データベースは通常、日付|時刻でソートされているとしましょう。次に、クエリはデータベースの姓と名で並べ替えられたコピーを作成します。安定した並べ替えでは元の順序が保持されるため、照会の比較には姓と名のみが含まれますが、各姓と名のトランザクションはデータ|時間順になります。

同様の例は、一度に3列にソートを制限する従来のExcelです。6列を並べ替えるには、最下位の3列で並べ替えを行い、その後に最上位の3列で並べ替えを行います。

安定した基数ソートの古典的な例は、基数10の数値列のフィールドでソートするために使用されるカードソーターです。カードは、最下位桁から最上位桁に並べ替えられます。各パスで、カードのデッキが読み取られ、その列の数字に従って10の異なるビンに分けられます。次に、カードの10ビンが順番に入力ホッパーに戻されます(最初に「0」カード、最後に「9」カード)。次に、すべての列がソートされるまで、次の列で別のパスが実行されます。カードには12のゾーンがあるため、実際のカードソーターには10を超えるビンがあり、列が空白になる可能性があり、ビンの読み取りに誤りがあります。文字を並べ替えるには、列ごとに2つのパスが必要です。1番目のパスは数字、2番目のパスは12 11ゾーンです。

後で(1937年)、フィールドを比較することによって2組のカードをマージできるカード照合(マージ)マシンがありました。入力は、マスターデッキとアップデートデッキの2つのソート済みカードデッキでした。コレーターは、2つのデッキを新しいマスタービンとアーカイブビンにマージしました。これらは、オプションでマスターの複製に使用され、複製の場合に新しいマスタービンには更新カードしかありません。これはおそらく、元の(ボトムアップ)マージソートの背後にあるアイデアの基礎でした。

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