Мені дуже цікаво, чому стабільність є чи не важливою в алгоритмах сортування?
IBM (Insertion, Bubble, Merge)
Мені дуже цікаво, чому стабільність є чи не важливою в алгоритмах сортування?
IBM (Insertion, Bubble, Merge)
Відповіді:
Кажуть, що алгоритм сортування є стабільним, якщо два об'єкти з однаковими клавішами відображаються в одному порядку в відсортованому виведенні, як вони з'являються у вхідному масиві для сортування. Деякі алгоритми сортування є стабільними за своєю природою, наприклад сортування вставки, сортування об'єднань, сортування міхурів тощо. А деякі алгоритми сортування не такі, як сортування кучи, швидкий сортування тощо.
Передумови : "стабільний" алгоритм сортування підтримує елементи з тим самим ключем сортування в порядку. Припустимо, у нас є список 5-літерних слів:
peach
straw
apple
spork
Якщо ми сортуємо список за першою літерою кожного слова, то стабільний сорт дасть:
apple
peach
straw
spork
У алгоритмі нестабільного сортування straw
або spork
можуть бути змінені, але у стабільному вони залишаються в однакових відносних положеннях (тобто, оскільки straw
з'являються раніше spork
на вході, він також з'являється передspork
на виході).
Ми могли б сортувати список слів за допомогою цього алгоритму: стабільне сортування за стовпцями 5, потім 4, потім 3, потім 2, потім 1. Зрештою, це буде правильно відсортовано. Переконайте себе в цьому. (до речі, цей алгоритм називається radix sort)
Тепер, щоб відповісти на ваше запитання, припустимо, у нас є список імен та прізвищ. Нас просять сортувати "за прізвищем, потім за першим". Ми могли б спочатку сортувати (стабільний чи нестабільний) за прізвищем, а потім стабільне сортування за прізвищем. Після цих сортів список в основному сортується за прізвищем. Однак там, де прізвища однакові, імена сортуються.
Ви не можете укладати нестабільні сорти однаково.
straw
і spork
порівняйте рівне. Стабільне сортування збереже порядок введення, тоді як нестабільне сортування не дає такої гарантії. "Правильно" залежить від програми. Функція сортування в більшості мов програмування дозволяє користувачеві надавати функцію замовлення. Якщо функція користувача розглядає різні елементи як рівні (наприклад, те саме ім’я, різні прізвища), це допомагає дізнатися, чи буде збережено початковий порядок. Дивіться функції сортування масивів OCaml для прикладу реального світу.
Стабільний алгоритм сортування - це той, який сортує ідентичні елементи у тому ж порядку, що і у вхідних даних, тоді як нестабільне сортування може не задовольнити випадок. - Я дякую моєму лектору з алгоритму Дідему Гозупеку за те, що він ознайомився з алгоритмами .
Алгоритми стабільного сортування:
Нестабільні алгоритми сортування:
Стабільність сортування означає, що записи одним і тим же ключем зберігають відносний порядок до і після сортування.
Тож стабільність має значення, якщо і лише в тому випадку, коли проблема, яку ви вирішуєте, потребує збереження цього відносного порядку.
Якщо вам не потрібна стабільність, ви можете скористатися швидким алгоритмом заповнення пам'яті з бібліотеки, наприклад, великим кутом або кварцветом, і забути про це.
Якщо вам потрібна стабільність, це складніше. Стабільні алгоритми мають більший об'єм процесора та / або пам'яті великого рівня, ніж нестабільні. Тож, коли у вас є великий набір даних, вам доведеться вибрати між биттям процесора або пам'яттю. Якщо ви обмежені як процесором, так і пам'яттю, у вас є проблеми. Хороший стабільний алгоритм компромісу - це двійковий сорт дерева; стаття у Вікіпедії має патетично просту реалізацію C ++ на основі STL.
Ви можете зробити нестабільний алгоритм у стабільний, додавши початковий номер запису як ключ останнього місця для кожного запису.
Це залежить від того, що ти робиш.
Уявіть, що у вас є записи людей з полем імені та прізвища. Спочатку ви сортуєте список за прізвищем. Якщо ви сортуєте список зі стабільним алгоритмом за прізвищем, у вас буде список, відсортований за іменем І прізвищем.
Є кілька причин, чому стабільність може бути важливою. Одне полягає в тому, що якщо дві записи не потрібно міняти своєю заміною, ви можете викликати оновлення пам'яті, сторінка позначена брудною і її потрібно переписати на диск (або інший повільний носій).
Кажуть, що алгоритм сортування є стабільним, якщо два об'єкти з однаковими клавішами відображаються в одному порядку в відсортованому виході, як вони з'являються у вхідному несортованому масиві. Деякі алгоритми сортування є стабільними за своєю природою, наприклад сортування вставки, сортування об'єднань, сортування міхурів тощо. А деякі алгоритми сортування не такі, як сортування кучи, швидкий сортування тощо.
Однак будь-яке дане сортування альго, яке не є стабільним, може бути модифіковане на стабільне. Можна сортувати конкретні алго способи зробити його стабільним, але в цілому будь-який алгоритм сортування на основі порівняння, який не є стабільним за своєю природою, може бути змінений на стабільний шляхом зміни операції порівняння ключів, щоб порівняння двох клавіш розглядало позицію як коефіцієнт для об'єктів з рівними клавішами.
Посилання: http://www.math.uic.edu/~leon/cs-mcs401-s08/handouts/stability.pdf http://en.wikipedia.org/wiki/Sorting_algorithm#Stability
Я знаю , що є багато відповідей на це, але мені ця відповідь , по Роберту Харві , резюмувати його набагато більш чітко:
Стабільний сортування - це такий, який зберігає початковий порядок вхідного набору, де алгоритм [нестабільний] не розрізняє два та більше елементів.
Якщо ви вважаєте, що ви сортуєте - це просто числа, і лише їх значення визначають / розрізняють їх (наприклад, елементи з однаковим значенням є тотожними), то питання стабільності сортування безглуздий.
Однак об'єкти з однаковим пріоритетом у сортуванні можуть бути виразними, і колись їх відносний порядок є значущою інформацією. У цьому випадку нестабільний сорт породжує проблеми.
Наприклад, у вас є список даних, який містить вартість часу [T] всіх гравців на очищення лабіринту з рівнем [L] в грі. Припустимо, нам потрібно ранжувати гравців за тим, наскільки швидко вони чистять лабіринт. Однак застосовується додаткове правило: гравці, які чистять лабіринт вищестоящим рівнем, завжди мають вищий ранг, незалежно від того, скільки тривалості витрат часу.
Звичайно, ви можете спробувати зіставити парне значення [T, L] на реальне число [R] за допомогою деякого алгоритму, який керується правилами, а потім класифікувати всіх гравців зі значенням [R].
Однак, якщо стабільне сортування можливо, ви можете просто сортувати весь список за [T] (Спочатку швидшими гравцями), а потім по [L]. У цьому випадку відносний порядок гравців (за часом витрат) не зміниться після того, як ви згрупуєте їх за рівнем лабіринту, який вони очистили.
PS: звичайно, підхід до сортування двічі не є найкращим вирішенням конкретної проблеми, але для пояснення питання про постер слід досить.
Стабільне сортування завжди буде повертати те саме рішення (перестановка) на одному вході.
Наприклад, [2,1,2] буде відсортовано за допомогою стабільного сортування як перестановки [2,1,3] (спочатку - індекс 2, потім індекс 1, потім індекс 3 у відсортованому виході). Це означає, що вихід завжди переміщується однаково. Інша нестабільна, але все-таки правильна перестановка - [2,3,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)]
але це не стійкий сорт.
Ще кілька прикладів того, чому потрібно бажання стабільних сортів. Бази даних є загальним прикладом. Візьміть до справи базу даних про трансакції, ніж включає прізвище | ім'я, дату | час покупки, номер товару, ціну. Скажімо, база даних зазвичай сортується за датою | часом. Тоді робиться запит, щоб зробити відсортовану копію бази даних за прізвищем | ім'ям, оскільки стабільний сортування зберігає початковий порядок, хоча порівняння запиту включає лише прізвище | ім'я, транзакції для кожного останнього | імені будуть бути в порядку | часу |
Аналогічний приклад - класичний Excel, який обмежує сортування одночасно трьома колонками. Для сортування 6 стовпців робиться сортування з найменш значущими 3 стовпцями, а потім сортування з найбільш значущими 3 стовпцями.
Класичний приклад стабільного сортування радіації - це сортувальник карт, який використовується для сортування за полем 10 числових стовпців. Карти відсортовані від найменш значущої до найзначнішої цифри. На кожному пропуску зчитується колода карт і розділяється на 10 різних бункерів відповідно до цифри в цьому стовпчику. Потім 10 бункерів картки повертаються назад у вхідний бункер за порядком (перші картки "0", "9" - останні). Потім черговий пропуск робиться наступним стовпцем, поки всі стовпці не будуть відсортовані. Фактичні сортувальники карт мають більше 10 бункерів, оскільки на картці є 12 зон, стовпець може бути порожнім, а також є неправильно прочитаний контейнер. Для сортування літер потрібно 2 проходи на стовпець, 1-й пропуск для цифри, 2-й пропуск для зони 12 11.
Пізніше (1937 р.) З'явилися машини для складання (злиття) карт, які могли об'єднати дві колоди карт, порівнюючи поля. Вхідними даними були дві вже відсортовані колоди карт, головна колода та колода оновлення. Коларатор об'єднав дві колоди в новий bin mater та архів, який необов'язково використовувався для головних дублікатів, щоб новий головний бін мав картки оновлення лише у випадку дублікатів. Це, мабуть, було підставою для ідеї, що стоїть за початковим сортом злиття (знизу вгору).