【问题标题】:Why is merge sort used by java to sort an array greater than elements 7为什么java使用归并排序对大于元素7的数组进行排序
【发布时间】:2013-05-11 08:44:21
【问题描述】:

Wikipedia

"在 Java 中,Arrays.sort() 方法使用归并排序或调优 快速排序取决于数据类型和实现效率 当少于七个数组元素时切换到插入排序 正在排序”

但是为什么呢?归并排序和快速排序都是 O(n log n)

【问题讨论】:

标签: java algorithm sorting


【解决方案1】:

算法的不同之处在于它们的典型情况行为,这也是插入排序最糟糕的地方之一。另一方面,对于非常小的集合 (n ≈ n2),插入排序更简单。

Java 的算法选择规则优先选择 QuickSort,并且由于特定限制而只回退到其他东西。 QuickSort,即,是一种不稳定 排序,因此仅适用于基元排序。对于引用类型,从 OpenJDK 7(以前的 MergeSort)开始使用 TimSort。

【讨论】:

  • 附加说明:插入排序在小集合上获胜,因为它具有较低的常数因子,而 big-O 不会记录。请注意,例如:n^2 < 10n 代表 n < 10
  • @Dukeling 是的,这就是我的观点。简单意味着低常数因子。
【解决方案2】:

这不是临时的:

Arrays.java 的排序方法对基元数组使用快速排序,对对象数组使用合并排序。

Why does Java's Arrays.sort method use two different sorting algorithms for different types?

另外,根据文档:

例如,sort(Object[]) 使用的算法不必是归并排序,但它必须是稳定的。

还有来自 javadoc 的另一个引用:

这种排序保证是稳定的:相等的元素不会 作为排序的结果重新排序。

实现说明:此实现是一个稳定的、自适应的、 需要远少于 n 次 lg(n) 比较的迭代归并排序 当输入数组部分排序时,同时提供 当输入数组为时传统归并排序的性能 随机排序。如果输入数组接近排序,则 实现需要大约 n 次比较。临时存储 要求从几乎排序的输入数组的小常数变化 对随机排序的输入数组的 n/2 个对象引用。

实现同样利用升序和降序 在其输入数组中排序,并且可以利用升序和 同一输入数组的不同部分按降序排列。它是 非常适合合并两个或多个排序数组:简单地连接 数组并对结果数组进行排序。

该实现改编自 Tim Peters 的 Python 列表排序 (时间排序)。

【讨论】:

    【解决方案3】:

    快速排序和合并排序在平均性能上都是 O(n log n)。在最坏的情况下,快速排序是 O(n^2)。

    【讨论】:

    • 他们的平均情况不是 O(n^2),而是 O(nlogn)。
    • 感谢您的关注。我专注于 n^2 最坏的情况,并意外输入了平均值。
    【解决方案4】:

    他们转向调整合并排序,因为从统计上发现,对于实际部分排序的数据集,这种方法可能比快速排序快一点。

    【讨论】:

    • Java 从未将 MergeSort 用于基元,也从未将 QuickSort 用于引用类型。
    • 他们是谁?请参考。
    • 那是Collections.sort。此外,它说的一样快。不过,我认为主要原因仍然是稳定性。
    【解决方案5】:

    Java 7 使用 Timsort - 合并和插入的混合体。事实上,它被广泛使用——android、Octave、python 也使用它。 http://en.wikipedia.org/wiki/Timsort

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-11
      • 1970-01-01
      • 2021-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多