Стабильность алгоритма быстрой сортировки

Quicksort нестабилен, поскольку он обменивает несмежные элементы.

Пожалуйста, помогите мне понять это утверждение.

Я знаю, как работает разделение, и какая стабильность. Но я не могу понять, что делает вышеизложенное причиной того, что это нестабильно? Тогда я считаю, что то же самое можно сказать и для сортировки слияния - хотя он цитируется как стабильный алгоритм.

Ответы

Ответ 1

Рассмотрим, что происходит во время раздела для следующего массива пар, где компаратор использует целое число (только). Строка просто там, так что у нас есть два элемента, которые сравниваются как бы равные, но на самом деле различимы.

(4, "first"), (2, ""), (3, ""), (4, "second"), (1, "")

По определению сортировка стабильна, если после сортировки два элемента, которые сравниваются как равные (два 4 s), появляются в том же порядке после этого, как и раньше.

Предположим, что в качестве поворота мы выбираем 3. Два элемента 4 будет в конечном итоге после него и 1 и 2, прежде чем он (там немного больше, чем это, я проигнорировал переместив точку опоры, поскольку он уже в правильном положении, но вы скажем, вы понимаете разделение).

Quicksorts вообще не дают никакой конкретной гарантии, что после раздела два 4 будут, и я думаю, что большинство реализаций отменили бы их. Например, если мы используем классический алгоритм разделения Hoare, массив разбивается следующим образом:

(1, ""), (2, ""), (3, ""), (4, "second"), (4, "first")

что нарушает стабильность сортировки.

Поскольку каждый раздел нестабилен, общий вид вряд ли будет.

Как указывает Steve314 в комментарии, сортировка слияния является стабильной при условии, что при слиянии, если вы сталкиваетесь с равными элементами, вы всегда выводите сначала тот, который поступает из "нижней части" двух половин, которые вы объединяете. То есть, каждое слияние должно выглядеть так, где "слева" - это сторона, которая поступает из нижнего уровня в исходном массиве.

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

Если <= были <, то слияние не было бы стабильным.

Ответ 2

Это будет похоже на то, что у пользователя есть отсортированный массив и сортируется по другому столбцу, всегда ли сохраняется алгоритм сортировки относительного порядка элементов, которые отличаются для предыдущего ключа сортировки, но имеют такое же значение в новом типе сортировки? Таким образом, в алгоритме A-сортировки, который всегда сохраняет порядок элементов (которые не отличаются от нового ключа сортировки), называется "устойчивым типом".

Please have a look of example

Ответ 3

Рассмотрим следующий массив пар:

{(4,'first');(2,'');(1,'');(4,'second');(3,'')}

Рассмотрим 3 как ось поворота. Во время выполнения Quick sort массив претерпевает следующие изменения:

  • {(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')}

Ясно, что из приведенного выше относительный порядок изменяется. Вот почему быстрый сорт называется "не обеспечивает стабильности".