Що таке стабільність в алгоритмах сортування і чому це важливо?


292

Мені дуже цікаво, чому стабільність є чи не важливою в алгоритмах сортування?


2
Для цілей паралелізації? наприклад: сортування злиття стабільне і може бути добре паралельне, як і швидкості.
DarthVader

13
Класичний QuickSort нестабільний
Костянтин Спірін

9
стабільний сорт algo -IBM (Insertion, Bubble, Merge)
roottraveller

Примітка для тих, хто може неправильно зрозуміти таке поняття, як я: Порядок рівних елементів гарантується збереженням. означає: якщо елементи в стабільному виді вважатимуться рівними, то вони б дотримувались попереднього порядку. Це не те, про що я думав: якщо елементи в попередньому порядку вважатимуться рівними, то в майбутньому стабільному сорті вони б дотримувались попереднього порядку. Хоча ви можете виявити, що останнє розуміння також має сенс у багатьох випадках.
Рік

Відповіді:


371

Кажуть, що алгоритм сортування є стабільним, якщо два об'єкти з однаковими клавішами відображаються в одному порядку в відсортованому виведенні, як вони з'являються у вхідному масиві для сортування. Деякі алгоритми сортування є стабільними за своєю природою, наприклад сортування вставки, сортування об'єднань, сортування міхурів тощо. А деякі алгоритми сортування не такі, як сортування кучи, швидкий сортування тощо.

Передумови : "стабільний" алгоритм сортування підтримує елементи з тим самим ключем сортування в порядку. Припустимо, у нас є список 5-літерних слів:

peach
straw
apple
spork

Якщо ми сортуємо список за першою літерою кожного слова, то стабільний сорт дасть:

apple
peach
straw
spork

У алгоритмі нестабільного сортування strawабо sporkможуть бути змінені, але у стабільному вони залишаються в однакових відносних положеннях (тобто, оскільки strawз'являються раніше sporkна вході, він також з'являється передspork на виході).

Ми могли б сортувати список слів за допомогою цього алгоритму: стабільне сортування за стовпцями 5, потім 4, потім 3, потім 2, потім 1. Зрештою, це буде правильно відсортовано. Переконайте себе в цьому. (до речі, цей алгоритм називається radix sort)

Тепер, щоб відповісти на ваше запитання, припустимо, у нас є список імен та прізвищ. Нас просять сортувати "за прізвищем, потім за першим". Ми могли б спочатку сортувати (стабільний чи нестабільний) за прізвищем, а потім стабільне сортування за прізвищем. Після цих сортів список в основному сортується за прізвищем. Однак там, де прізвища однакові, імена сортуються.

Ви не можете укладати нестабільні сорти однаково.


Отже, як би закликали сорт, щоб слова були у правильному порядку сортування яблучно-персикової спортивної соломи? Стабільний сорт дав нам яблучно-персикову соломку спорк, однак st повинен бути після sp (в алфавітному порядку), тож остаточним правильним сортом має бути яблучно-персикова спортивна солома
user1416486

2
@ user1416486: Ми сортуємо лише перший лист. З цим припущенням strawі sporkпорівняйте рівне. Стабільне сортування збереже порядок введення, тоді як нестабільне сортування не дає такої гарантії. "Правильно" залежить від програми. Функція сортування в більшості мов програмування дозволяє користувачеві надавати функцію замовлення. Якщо функція користувача розглядає різні елементи як рівні (наприклад, те саме ім’я, різні прізвища), це допомагає дізнатися, чи буде збережено початковий порядок. Дивіться функції сортування масивів OCaml для прикладу реального світу.
Джої Адамс

3
Я не розумію рядок .. однаковий ключ сортування ? Що ти тут маєш на увазі під ключем? Поясніть, будь ласка, твердження .. ідентичний ключ сортування
saplingPro

2
@saplingPro: "сортування ключа", я маю на увазі те, за чим ви сортуєте елементи. Отже, при сортуванні за першою літерою, тоді для кожного елемента його "ключ сортування" - це його перша літера.
Джої Адамс

12
Приклад - скажіть, що у вас є список з кожним пунктом, який містить інформацію про місце призначення рейсу та час відправлення. Ви спочатку сортуєте список залежно від часу. Потім ми їх сортуємо за призначенням. Якщо другий сорт стабільний, тепер усі рейси пов'язані до одного пункту призначення разом і в порядку збільшення часу відправлення. Якби вона не була стабільною, вони б не збільшували порядок часу.
roottraveller

55

Стабільний алгоритм сортування - це той, який сортує ідентичні елементи у тому ж порядку, що і у вхідних даних, тоді як нестабільне сортування може не задовольнити випадок. - Я дякую моєму лектору з алгоритму Дідему Гозупеку за те, що він ознайомився з алгоритмами .

Алгоритми стабільного сортування:

  • Сортування вставки
  • Об’єднати сортування
  • Сортування бульбашок
  • Тим Сортування
  • Підрахунок Сортування
  • Блок сортування
  • Квадсорт
  • Сортування бібліотеки
  • Коктейль шейкер Сортування
  • Gnome Sort
  • Непарний парний сорт

Нестабільні алгоритми сортування:

  • Купи сорту
  • Вибір сортування
  • Сорт раковини
  • Швидкий сорт
  • Інтросорт (за умови Quicksort)
  • Сорт дерева
  • Сортування циклу
  • Згладжує
  • Сортування турнірів (залежно від Хепсапсота)

введіть тут опис зображення


2
Ваші значення не рівні. Ви порівнюєте 9,7 і 9,8, але відповідно до перевірки стабільності вам потрібні ті ж значення, що і обидві 9,7 або обидва 9,8. І чим ті самі значення повинні бути впорядковані однаково в стабільних алгоритмах.
erhun

1
Ні, для перевірки стабільності ваші значення повинні бути однаковими. Я маю на увазі припущення, що ви використовуєте два 9,7 і називаєте їх у вузлі A і вузлі B. Якщо кожен порядок операцій сортування подібний A, B (замість них вони рівні), розумійте, що алгоритм сортування стабільний (як сортування злиття). Якщо порядок A, B змінюється при сортуванні їх кілька разів (1. сортування A, B, потім B, A знову A, B тощо), зрозумійте, що алгоритм сортування нестабільний (як швидке сортування) @snr
erhun

@snr [9, 6] відсутній у Input Array. Я думаю, ви мали на увазі [9, 8] в останній смузі масиву.
Усман

4
@erhun Я вважаю, що він сортує лише перший номер (той, що знаходиться перед комою) і використовує друге число просто як орієнтир, щоб побачити, що перший 9 відрізняється від другого 9.
Тіаго

20

Стабільність сортування означає, що записи одним і тим же ключем зберігають відносний порядок до і після сортування.

Тож стабільність має значення, якщо і лише в тому випадку, коли проблема, яку ви вирішуєте, потребує збереження цього відносного порядку.

Якщо вам не потрібна стабільність, ви можете скористатися швидким алгоритмом заповнення пам'яті з бібліотеки, наприклад, великим кутом або кварцветом, і забути про це.

Якщо вам потрібна стабільність, це складніше. Стабільні алгоритми мають більший об'єм процесора та / або пам'яті великого рівня, ніж нестабільні. Тож, коли у вас є великий набір даних, вам доведеться вибрати між биттям процесора або пам'яттю. Якщо ви обмежені як процесором, так і пам'яттю, у вас є проблеми. Хороший стабільний алгоритм компромісу - це двійковий сорт дерева; стаття у Вікіпедії має патетично просту реалізацію C ++ на основі STL.

Ви можете зробити нестабільний алгоритм у стабільний, додавши початковий номер запису як ключ останнього місця для кожного запису.


1
Стабільні алгоритми, такі як сортирування об'єднань, мають таку ж складність O (NlogN), як і Quicksort; постійний множник зусиль більший, хоча.
Джонатан Леффлер

Так, і використання пам’яті у сортуванні об'єднань становить O (N), а на Quicksort - O (log N). Причиною, про яку я згадував Quicksort, є те, що qsort () є стандартною програмою бібліотеки С, тому вона доступна.
Боб Мерфі

1
Найкраща загальна відповідь ІМХО. техніка з декількома ключами, згадана в інших, цікава, але завищена; застосувати його просто, але, як правило, набагато повільніше, ніж очевидні альтернативи (просто використовуйте один сорт із порівнянням з декількома ключами; або сортуйте за першим ключем, потім ідентифікуйте та сортуйте будь-які підлісти із дублікатами). Те, що стабільний сорт дає передбачуваний результат, може бути важливим у деяких додатках. Зокрема, якщо у вас є два вхідні списки A, B, які є ідентичними, крім списку B, має додатковий запис, виходи для стабільного сортування будуть ідентичними, за винятком того, що B має такий самий додатковий запис. І +1 за останній pgph.
greggo

16

Це залежить від того, що ти робиш.

Уявіть, що у вас є записи людей з полем імені та прізвища. Спочатку ви сортуєте список за прізвищем. Якщо ви сортуєте список зі стабільним алгоритмом за прізвищем, у вас буде список, відсортований за іменем І прізвищем.


4
Я думаю, ти маєш на увазі "прізвище І ім'я". Прізвище зазвичай є прізвищем.
Бейкони,

14

Є кілька причин, чому стабільність може бути важливою. Одне полягає в тому, що якщо дві записи не потрібно міняти своєю заміною, ви можете викликати оновлення пам'яті, сторінка позначена брудною і її потрібно переписати на диск (або інший повільний носій).


Що стосується заміни записів щодо стабільності?
користувач1683793

4

Кажуть, що алгоритм сортування є стабільним, якщо два об'єкти з однаковими клавішами відображаються в одному порядку в відсортованому виході, як вони з'являються у вхідному несортованому масиві. Деякі алгоритми сортування є стабільними за своєю природою, наприклад сортування вставки, сортування об'єднань, сортування міхурів тощо. А деякі алгоритми сортування не такі, як сортування кучи, швидкий сортування тощо.

Однак будь-яке дане сортування альго, яке не є стабільним, може бути модифіковане на стабільне. Можна сортувати конкретні алго способи зробити його стабільним, але в цілому будь-який алгоритм сортування на основі порівняння, який не є стабільним за своєю природою, може бути змінений на стабільний шляхом зміни операції порівняння ключів, щоб порівняння двох клавіш розглядало позицію як коефіцієнт для об'єктів з рівними клавішами.

Посилання: http://www.math.uic.edu/~leon/cs-mcs401-s08/handouts/stability.pdf http://en.wikipedia.org/wiki/Sorting_algorithm#Stability


3

Я знаю , що є багато відповідей на це, але мені ця відповідь , по Роберту Харві , резюмувати його набагато більш чітко:

Стабільний сортування - це такий, який зберігає початковий порядок вхідного набору, де алгоритм [нестабільний] не розрізняє два та більше елементів.

Джерело


1

Якщо ви вважаєте, що ви сортуєте - це просто числа, і лише їх значення визначають / розрізняють їх (наприклад, елементи з однаковим значенням є тотожними), то питання стабільності сортування безглуздий.

Однак об'єкти з однаковим пріоритетом у сортуванні можуть бути виразними, і колись їх відносний порядок є значущою інформацією. У цьому випадку нестабільний сорт породжує проблеми.

Наприклад, у вас є список даних, який містить вартість часу [T] всіх гравців на очищення лабіринту з рівнем [L] в грі. Припустимо, нам потрібно ранжувати гравців за тим, наскільки швидко вони чистять лабіринт. Однак застосовується додаткове правило: гравці, які чистять лабіринт вищестоящим рівнем, завжди мають вищий ранг, незалежно від того, скільки тривалості витрат часу.

Звичайно, ви можете спробувати зіставити парне значення [T, L] на реальне число [R] за допомогою деякого алгоритму, який керується правилами, а потім класифікувати всіх гравців зі значенням [R].

Однак, якщо стабільне сортування можливо, ви можете просто сортувати весь список за [T] (Спочатку швидшими гравцями), а потім по [L]. У цьому випадку відносний порядок гравців (за часом витрат) не зміниться після того, як ви згрупуєте їх за рівнем лабіринту, який вони очистили.

PS: звичайно, підхід до сортування двічі не є найкращим вирішенням конкретної проблеми, але для пояснення питання про постер слід досить.


0

Стабільне сортування завжди буде повертати те саме рішення (перестановка) на одному вході.

Наприклад, [2,1,2] буде відсортовано за допомогою стабільного сортування як перестановки [2,1,3] (спочатку - індекс 2, потім індекс 1, потім індекс 3 у відсортованому виході). Це означає, що вихід завжди переміщується однаково. Інша нестабільна, але все-таки правильна перестановка - [2,3,1].

Швидке сортування не є стабільним сортуванням, а перестановка різниць між тими ж елементами залежить від алгоритму вибору стрижня. Деякі реалізації вибираються випадковим чином, що може зробити швидке сортування, даючи різні перестановки на одному вході, використовуючи той самий алгоритм.

Алгоритм стійкого сортування необхідний детермінованим.


2
Це не те, що означає стабільність. Дивіться en.wikipedia.org/wiki/Sorting_algorithm#Stability
Луїс Олівейра

Я повинен виправити останнє речення, оскільки нестабільне сортування може виводити різне рішення навіть серед однієї і тієї ж реалізації, де будь-який стабільний сортування виводить те саме рішення.
Лука Ране

1
Чому -1? Чи може хтось вказати, будь ласка, що тут не так? Це не те, що є стабільним сортуванням, а тим, що має властивість стабільного сорту.
Лука Ране

Детермінований чи ні сорт, не визначає, чи є він стійким. Я можу написати нестабільний алгоритм детермінованого сортування, визначивши іншу поведінку розриву зв'язків (наприклад, замінивши не ключові частини). Стабільне сортування конкретно означає, що попередньо відсортований відносний порядок елементів зберігається при сортуванні зв’язків. Приклад виходу стабільного роду: 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)]але це не стійкий сорт.
коуберт

@cowbert Це більше твердження про приємне властивість, яке має кожен стабільний сорт. Це не має значення, якщо алгоритм чи реалізація стабільного сортування чи використання кожного разу буде мати однаковий результат. Важко підтримувати таке властивість серед різних нестабільних варіантів сортування.
Лука Ране

0

Ще кілька прикладів того, чому потрібно бажання стабільних сортів. Бази даних є загальним прикладом. Візьміть до справи базу даних про трансакції, ніж включає прізвище | ім'я, дату | час покупки, номер товару, ціну. Скажімо, база даних зазвичай сортується за датою | часом. Тоді робиться запит, щоб зробити відсортовану копію бази даних за прізвищем | ім'ям, оскільки стабільний сортування зберігає початковий порядок, хоча порівняння запиту включає лише прізвище | ім'я, транзакції для кожного останнього | імені будуть бути в порядку | часу |

Аналогічний приклад - класичний Excel, який обмежує сортування одночасно трьома колонками. Для сортування 6 стовпців робиться сортування з найменш значущими 3 стовпцями, а потім сортування з найбільш значущими 3 стовпцями.

Класичний приклад стабільного сортування радіації - це сортувальник карт, який використовується для сортування за полем 10 числових стовпців. Карти відсортовані від найменш значущої до найзначнішої цифри. На кожному пропуску зчитується колода карт і розділяється на 10 різних бункерів відповідно до цифри в цьому стовпчику. Потім 10 бункерів картки повертаються назад у вхідний бункер за порядком (перші картки "0", "9" - останні). Потім черговий пропуск робиться наступним стовпцем, поки всі стовпці не будуть відсортовані. Фактичні сортувальники карт мають більше 10 бункерів, оскільки на картці є 12 зон, стовпець може бути порожнім, а також є неправильно прочитаний контейнер. Для сортування літер потрібно 2 проходи на стовпець, 1-й пропуск для цифри, 2-й пропуск для зони 12 11.

Пізніше (1937 р.) З'явилися машини для складання (злиття) карт, які могли об'єднати дві колоди карт, порівнюючи поля. Вхідними даними були дві вже відсортовані колоди карт, головна колода та колода оновлення. Коларатор об'єднав дві колоди в новий bin mater та архів, який необов'язково використовувався для головних дублікатів, щоб новий головний бін мав картки оновлення лише у випадку дублікатів. Це, мабуть, було підставою для ідеї, що стоїть за початковим сортом злиття (знизу вгору).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.