quicksort和tuned quicksort有什么区别?

时间:2010-05-05 19:02:54

标签: java algorithm sorting quicksort

quicksort和tuned quicksort之间的根本区别是什么?快速排序的改进是什么? Java如何决定使用它而不是合并排序?

3 个答案:

答案 0 :(得分:7)

正如比尔蜥蜴说的那样,调整后的快速排序仍然具有与基本快速排序相同的复杂性 - O(N log N)平均复杂度 - 但是调整后的快速排序使用了一些不同的方法来尝试避免O(N ^ 2)最坏情况下的复杂性以及使用一些优化来减少N log N前面的常量,以获得平均运行时间。

最差案例时间复杂性

当每个步骤的分区的一侧始终具有零元素时,快速排序会发生最坏情况时间复杂性。当一个分区中的元素与另一个分区中的元素的比率非常远离1:1(例如10000:1)时,发生接近最坏情况的时间复杂度。这种最坏情况复杂性的常见原因包括但不限于:

  1. 一种快速排序算法,总是选择与子阵列具有相同相对索引的元素作为数据透视表。例如,对于已经排序的数组,一个快速排序算法总是选择子阵列的最左边或最右边的元素作为枢轴将是O(N ^ 2)。总是选择中间元素的快速排序算法为器官管阵列提供O(N ^ 2)([1,2,3,4,5,4,3,2,1]就是这个例子)。

  2. 不处理数组中重复/重复元素的快速排序算法可以是O(N ^ 2)。显而易见的例子是对包含所有相同元素的数组进行排序。显式地,如果快速排序将数组排序到像[< p | > = p],然后左侧分区将始终为零元素。

  3. 这些如何解决?第一种通常是通过随机选择枢轴来解决的。使用几个元素的中值作为枢轴也可以帮助,但排序的概率为O(N ^ 2)高于使用随机枢轴。当然,一些随机选择的元素的中位数也可能是明智的选择。三个随机选择的元素作为枢轴的中位数是一个常见的选择。

    第二种情况,重复元素,通常用Bentley-McIlroy paritioning(链接到pdf)或Dutch National Flag problem的解决方案来解决。然而,Bentley-McIlroy分区更常用,因为它通常更快。我想出了一种比它更快的方法,但这不是这篇文章的重点。

    <强>优化

    以下是上面列出的方法之外的一些常见优化,以帮助解决最坏的情况:

    1. 使用融合指针快速排序而不是基本快速排序。如果您想了解更多详情,请与我联系。

    2. 插入排序子阵列低于一定大小时。插入排序渐近为O(N ^ 2),但是对于足够小的N,它会快速排序。

    3. 使用具有显式堆栈的迭代快速排序而不是递归快速排序。

    4. 展开部分循环以减少比较次数。

    5. 将数据透镜复制到寄存器并使用数组中的该空间来减少交换元素的时间成本。

    6. 其他笔记

      Java在排序对象时使用mergesort,因为它是一个稳定的排序(保留了具有相同键的元素的顺序)。 Quicksort可以稳定或不稳定,但稳定版本比不稳定版本慢。

答案 1 :(得分:4)

“Tuned”quicksort意味着对basic algorithm应用了一些改进。通常,改进是尝试避免最坏情况下的时间复杂性。一些改进示例可能是选择枢轴(或多个枢轴),以便分区中永远不会只有一个密钥,或者只在分区超过某个最小大小时才进行递归调用。

看起来Java只在排序对象时使用合并排序(Arrays doc告诉你哪种排序算法用于哪种排序方法签名),所以我认为它不会真正“自行决定” ,但决定是提前做出的。 (另外,实施者可以自由使用另一种,只要它稳定。)

答案 2 :(得分:2)

在java中,Arrays.sort(Object [])使用合并排序,但所有其他重载排序函数都使用

插入排序,如果长度小于7,如果数组长度大于7,则使用

调整快速排序。