Він стабільний і має часову складність O (n). Це повинно бути швидшим, ніж такі алгоритми, як Quicksort і Mergesort, але я навряд чи коли-небудь бачу його використовувати.
Він стабільний і має часову складність O (n). Це повинно бути швидшим, ніж такі алгоритми, як Quicksort і Mergesort, але я навряд чи коли-небудь бачу його використовувати.
Відповіді:
На відміну від сортування radix, quicksort є універсальним, тоді як сортування radix корисне лише для цілочисленних клавіш довжини виправлення.
Також ви повинні розуміти, що O (f (n)) дійсно означає в порядку K * f (n), де K - деяка довільна константа. Для radix сортування цей K виявляється досить великим (принаймні порядок кількості бітів у цілих числах відсортованих), з іншого боку, quicksort має один з найнижчих K серед усіх алгоритмів сортування та середню складність n * log (n). Таким чином, у реальному житті сценарій швидкосполучення буде дуже швидким, ніж радіаційний сорт.
Більшість алгоритмів сортування мають загальне призначення. Враховуючи функцію порівняння, вони працюють над чим завгодно, і такі алгоритми, як Quicksort і Heapsort, будуть сортувати з додатковою пам'яттю O (1).
Сортування Radix є більш спеціалізованим. Вам потрібен певний ключ, який знаходиться в лексикографічному порядку. Вам потрібно одне відро для кожного можливого символу в ключі, а у відрах потрібно зберігати багато записів. (Крім того, вам потрібен один великий масив відер, який вміщатиме всі можливі ключові значення.) Ви, мабуть, потребуватимете значно більше пам’яті, щоб зробити радіаційне сортування, і ви будете використовувати його випадковим чином. Жодне з цього не добре для сучасних комп’ютерів, оскільки ви, ймовірно, отримаєте помилки сторінки, як-от Quicksort, отримають пропуски кешу.
Нарешті, люди взагалі більше не пишуть власні алгоритми сортування. Більшість мов мають бібліотечні засоби для сортування, і правильне, як правило, це використовувати. Оскільки radix сортування не є загальноприйнятним, воно, як правило, має бути адаптоване до фактичного використання та використовує багато додаткової пам’яті, важко ввести його у бібліотечну функцію чи шаблон.
O(n^2)
пам'яті в гіршому випадку через n
рекурсивні дзвінки на лівій і правій секціях. Якщо в реалізації використовується оптимізація хвостової рекурсії, її можна знизити до O(n)
тих пір, оскільки виклики до потрібного розділу не потребують додаткового місця. ( en.wikipedia.org/wiki/Quicksort#Space_complexity )
S(n) \in O(n)
місце для сортування за допомогою radix, тобто таке, як для купи або швидкого сортування.
n^2
про quicksort, але O(log n)
...
Досить рідко буває, що ключі, за якими ви сортуєтесь, - це фактично цілі числа у відомому, рідкому діапазоні. Зазвичай у вас є літерні поля, які виглядають , як вони будуть підтримувати несравнітельное сортування, але так як реальні строки не розподілені рівномірно за алфавітом, це не працюють , як і повинно бути в теорії.
В іншому випадку критерій визначається лише оперативно (з урахуванням двох записів, ви можете вирішити, який на першому місці, але ви не можете оцінити, наскільки "далеко" внизу шкали є ізольований запис). Тому метод часто не застосовується, менш застосовний, ніж ви можете вважати, або просто не швидший, ніж O (n * log (n)).
Я використовую його весь час, насправді більше, ніж порівняння на основі порівнянь, але я, правда кажучи, дивна куля, яка працює більше з числами, ніж будь-що інше (я ледь коли-небудь працюю зі струнами, і вони, як правило, інтерновані, якщо так, то в який момент радіакс сортування може бути знову корисним для фільтрації дублікатів та обчислення набірних перетинів; я практично ніколи не роблю лексикографічних порівнянь).
Основний приклад - радіаційне сортування точок за заданим виміром як частина пошуку або середній розкол або швидкий спосіб виявлення збіг точок, фрагментів сортування по глибині або радіаційне сортування масиву індексів, що використовуються в декількох петлях, щоб забезпечити більш зручний доступ до кешу шаблони (не повертаючись назад і назад лише в пам'яті, щоб повернутися знову і перезавантажити ту саму пам'ять у кеш-рядок). Принаймні в моєму домені (комп’ютерна графіка) є дуже широке застосування лише для сортування по 32-бітних та 64-бітних цифрових клавішах фіксованого розміру.
Я хотів би зафіксувати і сказати, що радіо-сортування може працювати на числа з плаваючою комою та мінуси, хоча складно написати версію FP, яка є максимально портативною. Крім того, хоча це O (n * K), K просто має бути кількістю байтів ключового розміру (наприклад: мільйон 32-бітових цілих чисел, як правило, займає 4 пропускні розміри в байтах, якщо у відрі є 2 ^ 8 записів ). Шаблон доступу до пам'яті також, як правило, набагато більш сприятливий для кешу, ніж quicksorts, хоча для цього потрібен паралельний масив і невеликий масив відра (другий, як правило, може добре розміщуватися на стеку). QS може зробити 50 мільйонів свопів для сортування масиву з мільйона цілих чисел із спорадичними шаблонами випадкового доступу. Сортування radix може це зробити за 4 лінійних, кешованих проходів над даними.
Однак, недостатня обізнаність про те, що можна зробити це за допомогою малого К, за від’ємними числами разом із плаваючою комою, може дуже суттєво сприяти відсутності популярності радіо-сортів.
Що стосується моєї думки щодо того, чому люди не користуються цим частіше, це може мати відношення до багатьох доменів, які, як правило, не мають потреби сортувати номери або використовувати їх як ключові слова пошуку. Однак, виходячи з мого особистого досвіду, багато моїх колишніх колег також не використовували його у випадках, коли це було ідеально підходить, і частково тому, що вони не усвідомлювали, що це може бути зроблено для роботи над ПП та негативів. Тож окрім того, що він працює лише на числових типах, часто вважається, що він є менш загальноприйнятим, ніж є насправді. Я б не використовував для нього майже такого ж використання, якби я вважав, що він не працює на числа з плаваючою комою та від'ємні цілі числа.
Деякі орієнтири:
Sorting 10000000 elements 3 times...
mt_sort_int: {0.135 secs}
-- small result: [ 12 17 17 22 52 55 67 73 75 87 ]
mt_radix_sort: {0.228 secs}
-- small result: [ 12 17 17 22 52 55 67 73 75 87 ]
std::sort: {1.697 secs}
-- small result: [ 12 17 17 22 52 55 67 73 75 87 ]
qsort: {2.610 secs}
-- small result: [ 12 17 17 22 52 55 67 73 75 87 ]
І це лише з моїм наївним реалізацією ( mt_sort_int
також сортування радіацією, але з більш швидкою гілкою коду, враховуючи, що він може вважати, що ключ є цілим числом). Уявіть, наскільки швидкою може бути стандартна реалізація, написана експертами.
Єдиний випадок, коли я виявив, що сортування radix походить гірше, ніж на основі дійсно швидкого порівняння C ++, - std::sort
це дійсно невелика кількість елементів, скажімо, 32, і тоді я вважаю, що std::sort
починає використовувати сорти, які краще підходять для найменшої кількості елементів, наприклад, купелів або сортування вставки, хоча в цей момент моя реалізація просто використовує std::sort
.
Ще одна причина: в наші дні сортування зазвичай реалізується за допомогою користувальницької процедури сортування, що додається до логіки сортування, що постачається компілятором. З радіальним сортуванням це було б значно складніше і стає ще гіршим, коли функція сортування діє на кілька клавіш змінної довжини. (Скажіть, ім'я та дату народження.)
У реальному світі я один раз реалізував радіаційний сорт. Це було в старі часи, коли пам’ять була обмежена, я не міг одразу привести всі свої дані в пам’ять. Це означало, що кількість доступу до даних набагато важливіше, ніж O (n) vs O (n log n). Я зробив один прохід через дані, розподіляючи кожен запис у відро (за списком яких записів, в яких бункерах, насправді нічого не переміщуючи). Для кожного непустого біна (мій ключ сортування був текст, було б багато порожні бункери) Я перевірив, чи можу я насправді занести дані в пам'ять - якщо так, введіть їх і використовуйте quicksort. Якщо ні, побудуйте тимчасовий файл, що містить лише елементи в bin, і викличте процедуру рекурсивно. (На практиці декілька бункерів переповнюватимуться.) Це спричинило два повних зчитування та одне повне записування до мережевого сховища і щось на зразок 10% від цього до локального сховища.
В наші дні такі проблеми з великими даними набагато важче зіткнутися, я, мабуть, ніколи більше нічого такого не напишу. (Якщо я зіткнувся з тими ж даними в ці дні, я б просто вказав 64-бітну ОС, додайте оперативну пам'ять, якщо ви потрапите в цей редактор.)
Якщо всі ваші параметри - цілі числа, і якщо у вас більше 1024 вхідних параметрів, то сортування радіації завжди швидше.
Чому?
Complexity of radix sort = max number of digits x number of input parameters.
Complexity of quick sort = log(number of input parameters) x number of input parameters
Отже, сортування радіоактивів швидше, коли
log(n)> max num of digits
Максимальне ціле число в Java - 2147483647. Що становить 10 цифр
Тож радіаційна сортування завжди швидша, коли
log(n)> 10
Тому сортування радікса завжди швидше, коли
n>1024