快速排序和优化的快速排序之间的根本区别是什么?快速排序的改进是什么?Java是如何决定使用这种排序而不是合并排序的?
发布于 2010-05-06 03:19:31
“调优”快速排序只是意味着对basic algorithm应用了一些改进。通常,改进是为了尽量避免最坏情况下的时间复杂性。一些改进的例子可能是选择枢轴(或多个枢轴),这样分区中永远不会只有一个键,或者只有当分区大于某个最小大小时才进行递归调用。
看起来Java只在对对象进行排序时才使用合并排序( Arrays doc会告诉你哪种排序算法用于哪种排序方法签名),所以我不认为它会自己“决定”,但这个决定是事先做出的。(而且,实现者可以自由地使用另一种类型,只要它是稳定的。)
发布于 2010-05-10 05:03:07
正如蜥蜴比尔所说,优化的快速排序仍然具有与基本快速排序相同的复杂度- O(N log N)平均复杂度-但优化的快速排序使用一些不同的方法来尝试避免O(N^2)最坏情况的复杂性,并使用一些优化来减少平均运行时间在N log N之前的常量。
最坏情况时间复杂度
当每个步骤的分区的一侧总是有零个元素时,快速排序会出现最坏的时间复杂度。当一个分区中的元素与另一个分区中的元素的比率远远不是1:1 (例如10000:1)时,就会出现接近最坏情况的时间复杂度。造成这种最坏情况复杂性的常见原因包括但不限于:
如何解决这些问题?第一个问题通常是通过随机选择轴心来修复的。使用几个元素的中位数作为轴心也会有所帮助,但排序为O(N^2)的概率高于使用随机轴心的概率。当然,一些随机选择的元素的中位数也可能是一个明智的选择。在这里,三个随机选择的元素的中位数作为枢轴是一种常见的选择。
第二种情况是重复元素,通常使用类似Bentley-McIlroy paritioning(链接到pdf)或Dutch National Flag problem的解决方案来解决。然而,Bentley-McIlroy分区更常用,因为它通常更快。我想出了一个比它更快的方法,但这不是这篇文章的重点。
Optimizations
以下是上面列出的方法之外的一些常见优化,以帮助应对最坏的情况:
其他备注
Java在对对象进行排序时使用mergesort,因为它是一种稳定的排序(保留了具有相同键的元素的顺序)。快速排序可以是稳定的或不稳定的,但稳定的版本比不稳定的版本慢。
发布于 2010-05-06 03:37:48
在java中,Arrays.sort(Object[])使用合并排序,但所有其他重载排序函数都使用
如果长度小于7,则插入排序;如果数组长度大于7,则使用
调整了快速排序。
https://stackoverflow.com/questions/2776011
复制相似问题