Arrays.sort
Метод Java 6 использует быструю сортировку для массивов примитивов и сортировку слиянием для массивов объектов. Я считаю, что в большинстве случаев Quicksort быстрее, чем сортировка слиянием, и требует меньше памяти. Мои эксперименты подтверждают это, хотя оба алгоритма - O (n log (n)). Так почему же для разных типов используются разные алгоритмы?
121
Integer
s или что-то в этом роде?Ответы:
Наиболее вероятная причина: быстрая сортировка нестабильна , т. Е. Одинаковые записи могут менять свое относительное положение во время сортировки; среди прочего, это означает, что если вы отсортируете уже отсортированный массив, он может не остаться неизменным.
Поскольку примитивные типы не имеют идентичности (невозможно различить два int с одинаковым значением), для них это не имеет значения. Но для ссылочных типов это может вызвать проблемы для некоторых приложений. Поэтому для них используется стабильная сортировка слиянием.
OTOH, причина не использовать стабильную сортировку слиянием (гарантированный n * log (n)) для примитивных типов может заключаться в том, что для этого требуется создание клона массива. Для ссылочных типов, где упомянутые объекты обычно занимают гораздо больше памяти, чем массив ссылок, это обычно не имеет значения. Но для примитивных типов клонирование массива напрямую удваивает использование памяти.
источник
Согласно документам API Java 7, процитированным в этом ответе ,
Arrays#Sort()
для массивов объектов теперь используется TimSort , который является гибридом MergeSort и InsertionSort. С другой стороны,Arrays#sort()
для примитивных массивов теперь используется Dual-Pivot QuickSort . Эти изменения были реализованы начиная с Java SE 7.источник
Одна из причин, по которой я могу думать, заключается в том, что быстрая сортировка имеет наихудшую временную сложность O ( n ^ 2 ), в то время как mergesort сохраняет время наихудшего случая O ( n log n ). Для массивов объектов справедливо ожидать, что будет несколько повторяющихся ссылок на объекты, что является одним из случаев, когда быстрая сортировка работает хуже всего.
Есть приличное визуальное сравнение различных алгоритмов , обратите внимание на правый график для разных алгоритмов.
источник
Я посещал курс Coursera по алгоритмам, и на одной из лекций профессор Боб Седжвик упомянул об оценке сортировки системы Java:
источник
java.util.Arrays использует быструю сортировку для примитивных типов, таких как int, и mergesort для объектов, которые реализуют Comparable или используют Comparator . Идея использования двух разных методов заключается в том, что если программист использует объекты, возможно, пространство не является критически важным соображением, и поэтому дополнительное пространство, используемое слиянием, возможно, не проблема, и если программист использует примитивные типы, возможно, производительность является наиболее важной вещью, поэтому используйте быстрая сортировка .
Например: это пример, когда важна стабильность сортировки.
Вот почему стабильные сортировки имеют смысл для типов объектов, особенно для изменяемых типов объектов и типов объектов с большим количеством данных, чем просто ключ сортировки, и сортировка слиянием является такой сортировкой. Но для примитивных типов стабильность не имеет значения. Бессмысленно.
Источник: ИНФО
источник
Arrays.sort
Метод Java использует быструю сортировку, сортировку вставкой и сортировку слиянием. В коде OpenJDK реализованы даже как одинарная, так и двойная быстрая сортировка. Самый быстрый алгоритм сортировки зависит от обстоятельств, и победителями являются: сортировка вставкой для небольших массивов (в настоящее время выбрано 47), сортировка слиянием для в основном отсортированных массивов и быстрая сортировка для оставшихся массивов, поэтому Java Array.sort () пытается выбрать лучший алгоритм для подать заявку на основании этих критериев.источник