2013-04-30 3 views
6

Из того, что я прочитал (кратко), Java и Python выглядят так, как будто они используют timsort в своих стандартных библиотеках, тогда как метод сортировки в stdlib C называется qsort, потому что однажды он был quicksort.Как различные языки выполняют сортировку в своих стандартных библиотеках?

Какой алгоритм в настоящее время используют стандартные языки в своих стандартных библиотеках и почему они выбрали этот алгоритм? Кроме того, C отклонился от быстрой сортировки?

Я знаю, что этот вопрос не имеет «актуальных проблем, с которыми я сталкиваюсь», и может показаться открытыми для некоторых, но знание того, как/почему определенные алгоритмы выбраны в качестве стандартных, кажется довольно полезным, но относительно неопытным. Я также чувствую, что в глубине ответа, касающегося проблем, которые зависят от языка (типы данных?) И специфических для машины (кеш-хиты?), Можно было бы лучше понять, как работают разные языки и алгоритмы, чем унифицировать.

ответ

0

библиотека моей машины C обеспечивает qsort, heapsort и mergesort, говоря в man page:

Функции qsort() и qsort_r() являются реализация C.A.R. Алгоритм «quicksort» Хора, вариант сортировки разделов; в частности, см. D.E. Knuth's Алгоритм Q. Quicksort принимает O (n lg n) среднее время. Эта реализация использует медианный выбор, чтобы избежать его O (n) худшее поведение.

heapsort() Функция представляет собой реализацию J.W.J. Алгоритм Уильяма «heapsort», вариант сортировки выбора; в частности, см. D.E. Knuth's Алгоритм H. Heapsort принимает O (n lg n) наихудшее время. Его единственным преимуществом над qsort() является то, что он не использует почти никакой дополнительной памяти; в то время как qsort() не выделяет память, это с использованием рекурсии.

Функция mergesort() требует дополнительной памяти размером nel * width байт; его следует использовать только в том случае, если пространство не стоит на высоте. Функция mergesort() оптимизирована для данных с уже существующим порядком; его наихудшее время - O (n lg n); его лучшим случаем является O (n).

Обычно qsort() быстрее, чем mergesort() который быстрее, чем heapsort(). Доступность памяти и уже существующий порядок в данных могут сделать это неверным.

Есть много библиотек с открытым кодом C, на которые вы можете посмотреть, хотите ли вы увидеть конкретные детали реализации.

Насколько «почему система X выбрала алгоритм Y», это довольно сложный вопрос для значимого ответа - если вам не повезло найти обоснование в документации, вам придется напрямую спросить дизайнеров ,

+0

Я считаю, что OSX уникален тем, что в него включены и heapsort, и mergesort. Обе машины, над которыми я работаю, и мой uni-сервер не хватает ничего, кроме qsort и qsort_r. Кроме того, я знаю, что вопрос довольно сложно спросить, потому что он включает в себя много истории, может быть, какую-то политику, определенно некоторое интимное понимание различных систем и много чтения. Это вопрос, который, если бы не финальная неделя, я бы, вероятно, попытался ответить сам. Но даже в этом случае много исследований. Я надеялся, что кто-то там увлекся этим ответом в более ранний момент времени. – lakechfoma

+0

Да, это вполне возможно. Моя точка зрения в основном заключается в том, что за пределами документации или взглядов на реализацию, о которой вы заботитесь напрямую, информации не так много. –

+0

Да, я так понял. Я надеялся, что если будет принято решение в публичных списках рассылки или что у вас есть, кто-то там запомнит процесс принятия решений и обеспечит понимание. – lakechfoma

0

Я сделал быстрое сканирование в стандарте C11 о qsort(), и я не мог найти никаких упоминаний о том, как qsort() должны быть реализованы и ожидаемое время/пространство сложность алгоритма. Все, что он должен сказать, это о некоторых условиях относительно функции компаратора .

Что это означает, что реализация может выбрать любой алгоритм, основанный на компараторе, который подходит с qsort(). Например, реализация может использовать наивный алгоритм, такой как bubble sort для реализации qsort(), который не так эффективен, как реальный quick sort. Итог заключается в том, что для реализации фактического алгоритма до реализации необходимо принять решение.

+0

Важной вещью, полученной при чтении стандарта, является то, что 'qsort' не имеет интерфейса для сообщения об ошибке и, следовательно, не может возвращаться без сортировки ввода. Это в основном ограничивает разработчиков каким-либо использованием алгоритмов на месте или обеспечивает резервный локальный алгоритм при сбое памяти. –

1

C не определяет алгоритм, который будет использоваться qsort.

В текущем glibc (2.17) qsort выделяет память (используя malloc или alloca, если требуемая память действительно мала) и использует алгоритм сортировки слиянием. Если требования к памяти слишком высоки или если malloc не работает, он использует алгоритм быстрой сортировки.

+0

Я подозреваю, что он по-прежнему использует introsort, а не просто quicksort, в случае сбоя. Но я не проверил. –

+0

Ну, я проверил, и насколько я понял код, он быстро сортируется. Также для информации их реализация quicksort использует простую сортировку вставки, когда раздел небольшой (<4 элемента). – ouah

+0

Introsort - это вариант быстрой сортировки glibc, который отслеживает соотношение последовательных размеров разделов, чтобы определить, когда он может попасть в наихудший вариант O (n²), и переключиться на heapsort в этом случае. Интересно, почему они используют сортировку вставки для небольших разделов, хотя ...делать листья с сортировочными сетями должно быть намного лучше. –

1

В musl, мы используем Smooth Sort. Концептуально это вариант сортировки кучи (и аналогично времени на месте и O (n log n)), но у него есть приятное свойство, что наихудшая производительность приближается к O (n) для уже отсортированного или почти сортированного ввода. Я не уверен, что это лучший выбор, но очень сложно сделать лучше с помощью локального алгоритма с O (n log n) в худшем случае.

Будучи малоизвестным изобретением Дийкстры, он также делает его прохладным. :-)

+0

Мне нужно потратить некоторое время на чтение муслика и гладкости сейчас! Просто просмотр обеих страниц вызвал у меня интерес. Гладкая сортировка выглядит довольно симпатичным, интересным алгоритмом. – lakechfoma