Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么Collections.sort使用合并排序而不是快速排序?_Java_Sorting_Collections - Fatal编程技术网

Java 为什么Collections.sort使用合并排序而不是快速排序?

Java 为什么Collections.sort使用合并排序而不是快速排序?,java,sorting,collections,Java,Sorting,Collections,我们知道快速排序是最快的排序算法 JDK6collections.sort使用合并排序算法而不是快速排序。但是Arrays.sort使用快速排序算法 Collections.sort使用合并排序而不是快速排序的原因是什么 很可能来自Josh Bloch: 我确实写了这些方法,所以我想我有资格回答。它是 的确,没有单一的最佳排序算法。快速排序 与mergesort相比,有两个主要缺陷: 它不稳定(正如帕西法尔所指出的) 它不保证n log n性能;它可以退化为病理输入的二次性能 对于基元类型来说,

我们知道快速排序是最快的排序算法

JDK6
collections.sort
使用合并排序算法而不是快速排序。但是Arrays.sort使用快速排序算法


Collections.sort使用合并排序而不是快速排序的原因是什么

很可能来自Josh Bloch:

我确实写了这些方法,所以我想我有资格回答。它是 的确,没有单一的最佳排序算法。快速排序 与mergesort相比,有两个主要缺陷:

  • 它不稳定(正如帕西法尔所指出的)

  • 它不保证n log n性能;它可以退化为病理输入的二次性能

  • 对于基元类型来说,稳定性不是问题,因为不存在 区别于(价值)平等的同一性。以及 二次行为在实践中被认为不是一个问题 Bentely和McIlroy的实现(或随后的for),这就是为什么这些快速排序变体用于 原始种类

    对任意对象进行排序时,稳定性是一件大事。例如 假设您有表示电子邮件的对象,并对其进行排序 先按日期,然后按发件人。你希望它们按顺序排列 每个发件人内的日期,但只有在排序为 马厩。这就是我们选择提供稳定排序(合并排序)的原因 对对象引用进行排序。(从技术上讲,多序列 稳定排序会在 排序的相反顺序:最后的排序决定最大 有效子键。)

    合并排序保证n log n(时间),这是一个很好的附带好处 无论输入的是什么,性能都是一样的。当然也有不利的一面: 快速排序是一种“就地”排序:它只需要logn外部空间 (以维护调用堆栈)。另一方面,合并、排序, 需要O(n)外部空间。TimSort变量(在Java中引入) 如果输入阵列为 差不多分类了

    此外,报告还涉及:

    java.util.Arrays.sort和(间接)by使用的算法 排序对象引用是一个“修改的 mergesort(其中,如果 “低子列表小于高子列表中的最低元素)。” 是一个相当快的稳定排序,它保证O(n logn) 性能和需要O(n)额外空间。在它的时代(它是被写的) 1997年由约书亚·布洛赫(Joshua Bloch)执导),这是一个不错的选择,但今天我们可以 做得更好

    自2003年以来,Python的列表排序使用了一种称为timsort的算法 (作者蒂姆·彼得斯之后)。它是一种稳定的、自适应的、迭代的方法 在以下情况下,需要远远少于n个日志(n)比较的mergesort 在部分排序的阵列上运行,同时提供性能 与在随机数组上运行的传统合并排序相当。喜欢 所有正确的合并排序都是稳定的,并且在O(n logn)时间内运行 (最坏情况)。在最坏的情况下,timsort需要临时存储 n/2个对象引用的空间;在最好的情况下,它只需要一个 小而恒定的空间。将此与当前的情况进行对比 实现,它总是需要n个对象的额外空间 引用,而beats n log n仅在几乎排序的列表上

    这里详细介绍了Timsort:

    Tim Peters最初的实现是用C.Joshua Bloch编写的 将它从C移植到Java,并对 生成的代码非常复杂。生成的代码是一个插入 替换java.util.Arrays.sort。在高度有序的数据上,此 代码的运行速度是当前实现的25倍(在 热点服务器(虚拟机)。在随机数据上,新旧数据的速度 实现是可比较的。对于非常短的列表,新的 实现速度大大快于旧版本,即使是随机的 数据(因为它避免了不必要的数据复制)

    另外,请参见


    没有一个“最佳”选择。与其他许多事情一样,这是一个权衡问题。

    除非你能找到一位JDK作者来回答,否则你只会得到猜测。这不是一个真正的问题。@EJP的观点很好,但肯定“不是建设性的”是正确的结束理由。我很清楚这里的问题是什么,因为Java的人决定这样做。问问他们。我想你在这里找不到合理的答案。快速排序并不是最好的。它只适合一般用途。一个猜测是:快速排序不稳定,合并排序不稳定。对于原语,稳定/非稳定排序是不相关的,对于对象,它可能是(或者至少,您可能会针对不稳定排序提交bug)。@EJP,没有什么能阻止JDK作者公开其意图。一旦公开,我们不需要作者自己来回答。事实上,即使没有JDK作者的回答,也有可能得到比猜测更多的答案。