什么是Java的排序算法

时间:2012-09-01 14:41:42

标签: java algorithm sorting

java如何在内部对数据类型进行排序?为什么?如果可以提到特定的算法,那将是很好的

3 个答案:

答案 0 :(得分:20)

从版本7开始,Oracle的Java实现对大于10个元素的对象数组使用Timsort,对于具有少于该元素数量的数组使用Insertion sort。同样的考虑适用于Arrays.sort()Collections.sort()。在旧版本的Java中,使用了Merge sort而不是Timsort。

该语言的其他实现(除了Oracle之外)可能使用不同的排序算法,因为规范并未强制要求。引用Collections'documentation

  

此类中包含的多态算法的文档通常包括实现的简要说明。这些描述应被视为实施说明,而不是规范的一部分。只要遵守规范本身,实现者就可以随意替换其他算法。 (例如,sort使用的算法不一定是mergesort,但它必须是稳定的。)

对于数字基元的排序,JDK 7 uses“双枢轴快速排序”。

答案 1 :(得分:6)

Collections.sort()使用修改后的mergesort。 Arrays.sort()为基元使用快速排序的变体,为Object排序使用合并排序。

对于Java 7,请阅读@SebastianPaaskeTørholm下面的评论

答案 2 :(得分:3)

确定尝试列出规范列表。基本上,契约是Collections.sort必须是“稳定”的排序(即,将不重新排列相等的元素),其中Arrays.sort(对于本机类型数组)可以重新排列它们,因为它们是相同的,因此使用不同(即更快)的算法具有更大的自由度。 here给出了希望获得稳定合同的理由。还假定比较对象(相对于本机)“要贵得多”(通常比较昂贵),因此Collections.sort的附带目标是使比较次数最少并保持稳定。

对于所有版本,Collections.sort首先创建列表的副本(到数组),对其进行修改,然后将排序后的元素复制回到初始列表中,并复制到avoid O(n ^ 2 )排序链表的复杂性。猜猜他们认为多余的副本不会太昂贵,因为它只是在复制引用,而不是实际值(?)。

在JDK 6中:

本机类型的数组tuned quicksort

 * The sorting algorithm is a tuned quicksort, adapted from Jon
 * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
 * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
 * 1993).  This algorithm offers n*log(n) performance on many data sets
 * that cause other quicksorts to degrade to quadratic performance.

对于此修改后的快速排序,认为二次“最坏情况” O(n ^ 2)行为是not a problem

performance选择了Quicksort本身。

对象列表modified mergesort

 * The sorting algorithm is a modified mergesort (in which the merge is
 * omitted if the highest element in the low sublist is less than the
 * lowest element in the high sublist).  This algorithm offers guaranteed
 * n log(n) performance. 

“它is相当快速,稳定的排序,可保证O(n log n)性能并需要O(n)额外空间。”

它也默认为small arrays的插入排序。

JDK 7:

本机类型的数组dual-pivot quicksort

 * ...The sorting algorithm is a Dual-Pivot Quicksort
 * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm
 * offers O(n log(n)) performance on many data sets that cause other
 * quicksorts to degrade to quadratic performance, and is typically
 * faster than traditional (one-pivot) Quicksort implementations.

“新算法reduces的平均交换次数减少了20%。”

还有are个特定阈值,如果大小在“ x之下”,它将仅进行计数排序,插入排序或快速排序,而不是“双枢轴快速排序”。 (取决于要排序的原语类型)https://stackoverflow.com/a/41129231/32453

对象列表Timsort一种hybrid合并/插入排序。

“这是一个稳定的,自适应的,迭代的合并排序,在部分排序的数组上运行时,所需的比较少于n log(n)个比较,而在随机数组上运行时,其性能可与传统的合并排序相提并论。稳定并且运行时间为O(n log n)(最坏的情况),在最坏的情况下,timsort需要临时存储n / 2个对象引用的存储空间;在最好的情况下,timsort只需要很小的恒定空间即可。在当前的实现中,这总是需要额外的空间来存储n个对象引用,并且仅在几乎排序的列表上才达到n log n。”

“在高度排序的数据上,此代码的运行速度是当前实现的25倍。”

“ 1)Guaranteed O(n * log(n))或具有较低常数的较少比较。2)预排序(或重新排序)数据的精确n-1比较。3)稳定排序。” < / p>

您可以还原为在环境中使用LegacyMergeSort。设置。

JDK 8:

本机类型数组dual-pivot quicksort,对jdk 7做了一些小的修改(是什么?)。

对象列表:Timsort(相同)

并行排序:???

JDK 9:

本机类型的数组dual-pivot quicksort,至少带有一些小的modifications,因此,如果数据“按顺序排列”,它将对它进行修改后的合并排序。

对象列表:Timsort(相同)

并行排序:???

JDK 10:

本机类型的数组:dual-pivot quicksort,已经进行了proposed的一些修改。

对象列表:Timsort(相同)

并行排序:???

这是一个社区Wiki,可以随时对其进行更新和/或详细说明。