クイックソートは隣接していない要素を交換するため、安定していません。
この声明を理解するのを手伝ってください。
パーティショニングの仕組みと安定性について知っています。しかし、これが安定しない理由として上記の原因を理解できませんか?次に、マージソートについても同じことが言えます。ただし、安定したアルゴリズムであるとされています。
コンパレーターが整数(のみ)を使用する次のペアの配列のパーティション中に何が発生するかを検討します。文字列はそこにあるので、2つの要素は等しいかのように比較されますが、実際には区別できます。
(4, "first"), (2, ""), (3, ""), (4, "second"), (1, "")
定義により、ソートは、stableです。ソート後、等しいと比較される2つの要素(2つの4
s)は、その後同じ順序で表示されます。前。
ピボットとして3
を選択するとします。 2つの4
要素はその後になり、1
とその前に2
があります(それより少し多いので、ピボットの移動は無視しています)正しい位置ですが、パーティショニングを理解していると言います)。
クイックソートは一般に、特定の保証を与えませんwhereパーティションの後に2つの4
sがあり、ほとんどの実装はそれらを逆にします。たとえば、 Hoareの従来のパーティショニングアルゴリズム を使用すると、配列は次のようにパーティション化されます。
(1, ""), (2, ""), (3, ""), (4, "second"), (4, "first")
これはソートの安定性に違反します。
各パーティションは安定していないため、全体的なソートは安定しているとは言えません。
Steve314がコメントで指摘しているように、マージソートは安定していますが、マージ時に等しい要素に遭遇した場合、常に、マージする2つの半分の「下位」からの要素を最初に出力します。つまり、各マージは次のようになります。「左」は元の配列の下から下に来る側です。
while (left not empty and right not empty):
if first_item_on_left <= first_item_on_right:
move one item from left to output
else:
move one item from right to output
move everything from left to output
move everything from right to output
<=
が<
の場合、マージは安定しません。
それは、ユーザーが並べ替えられた配列を持ち、別の列で並べ替えているようなものです。並べ替えアルゴリズムは、前の並べ替えキーとは異なるが新しい並べ替えキーで同じ値を持つ要素の相対順序を常に保持しますか?そのため、要素の順序を常に維持する(新しい並べ替えキーでは変わらない)並べ替えアルゴリズムでは、「安定した並べ替え」と呼ばれます。
次のペアの配列を考えます。
{(4,'first');(2,'');(1,'');(4,'second');(3,'')}
3をピボットと見なします。クイックソートの実行中、配列は次のように変更されます。
{(4,'first');(2,'');(1,'');(4,'second');(3,'')}
{(2,'');(4,'first');(1,'');(4,'second');(3,'')}
{(2,'');(1,'');(4,'first');(4,'second');(3,'')}
{(2,'');(1,'');(3,'');(4,'second');(4,'first')}
{(1,'');(2,'');(3,'');(4,'second');(4,'first')}
上記から明らかなように、相対的な順序が変更されています。これが、クイックソートが「安定性を保証しない」と言われている理由です。
同等のアイテムの順序が保持されている場合、ソートは安定していると言えます。クイックソートの安定性は、パーティショニング戦略に依存します。 「Quicksortは隣接していない要素を交換するため、安定していません。」このステートメントは、Hoareパーティション分割が使用されているという前提条件に依存しています。これは、Berkeley CS61bのHoareパーティショニングデモです Hoare Partitioning
「隣接していない要素を交換する」の意味を知っておく必要があります。