У меня проблемы с поиском хороших ресурсов, которые дают наихудший случай на месте стабильного алгоритма сортировки. Кто-нибудь знает какие-нибудь хорошие ресурсы?
Просто напоминание, означает, что он использует переданный массив, а алгоритму сортировки разрешено использовать только постоянное дополнительное пространство. Стабильный означает, что элементы с одинаковым ключом отображаются в отсортированном массиве в том же порядке, что и в оригинале.
Например, сортировка наивного слияния является наихудшим вариантом и стабильна, но использует O ( n ) дополнительное пространство. Стандартная быстрая сортировка может быть сделана стабильной, она на месте, но в худшем случае O ( n 2 ) . Heapsort на месте, в худшем случае O ( n ln n ), но не стабильный. В Википедии есть хорошая диаграмма того, какие алгоритмы сортировки имеют какие недостатки. Обратите внимание, что в списке нет алгоритма сортировки, который имеет все три условия устойчивости, наихудший случай O ( n ln ) и быть на месте.
Я нашел статью под названием «Практическая сортировка на месте», выполненную Катаяйненом, Пасаненом и Теухолой, в которой утверждается, что в худшем случае вместо стабильного варианта слияния. Если я правильно понимаю их результаты, они используют (снизу вверх?) Mergesort рекурсивно на первом 1 массива и последний1 из массива и использовать второй1 как царапать пространство, чтобы сделать слияние. Я все еще читаю это, так что любая дополнительная информация о том, правильно ли я интерпретирую их результаты, ценится.
Я также был бы очень заинтересован в наихудшем случае вместо стабильной быстрой сортировки. Из того, что я понимаю, изменение быстрой сортировки в худшем случае O ( n ln n ) требует выбора правильной оси центра, который разрушил бы стабильность, которой он обычно мог бы пользоваться.
Это чисто теоретический интерес, и у меня нет практического применения. Я просто хотел бы знать алгоритм, который имеет все эти три функции.
Ответы:
Есть несколько алгоритмов, описанных выше, и почти все они были изобретены за последние 30 лет.
Вероятно, самым хорошим является класс алгоритмов, называемых сортировкой блоков , в том числе версия (названная WikiSort) Кимом и Кутцнером в 2008 году. Она не только стабильна и полностью на месте (O (1) накладные расходы памяти в трандихотомной модели), она также является адаптивным и, таким образом, предпринимает меньше шагов для сортировки почти отсортированных списков, сходясь к O (n) сравнениям в случае уже отсортированного списка. Вы можете найти реализацию в C, C ++ и Java здесь: https://github.com/BonzaiThePenguin/WikiSort
Также представляет интерес алгоритм GrailSort (также сортировка по блокам) Хуанга и Лэнгстона (1989-1992), который фактически превосходит WikiSort в нескольких типах тестовых случаев. Реализация на C ++ доступна здесь: https://github.com/Mrrl/GrailSort
источник
Вы можете написать стабильную сортировку на месте. Смотрите это для деталей. По словам самого автора:
Я не буду копировать код здесь, но вы можете найти его по ссылке или проверив C ++ STL. Пожалуйста, дайте мне знать, если вы хотите, чтобы я попытался предоставить более подробное описание того, что здесь происходит.
источник
Пожалуйста, примите это как длинный комментарий к некоторым практическим соображениям. Хотя это не ответ на ваш вопрос, я думаю, что вас может заинтересовать это обсуждение Python:
Источник: bugs.python.org , автор: Тим Питерс
Также обратите внимание, что Timsort хорошо работает с уже отсортированными массивами.
Таким образом, Python использует Timsort (то есть Mergesort с некоторыми изменениями), и, как я искал реализацию Java несколько лет назад, это была также Mergesort (я думаю, что теперь они также используют Timsort).
источник