【问题标题】:Why does quicksort exclude the middle element but mergesort includes it?为什么快速排序排除了中间元素而归并排序包含了它?
【发布时间】:2019-04-01 17:36:50
【问题描述】:

我正在讨论快速排序的实现(来自 CLRS 第 3 版)。我发现数组的递归除法从低索引到中间1,然后再从中间+1到高。

QUICKSORT(A,p,r)
1 if(p < r)
2        q = PARTITION(A,p,r)
3        QUICKSORT(A,p,q-1)
4        QUICKSORT(A,q+1,r)

并给出归并排序的实现如下:

MERGE-SORT(A,p,r)
1 if(p < r)
2       q = (p+r)/2 (floor)
3       MERGE-SORT(A,p,q)
4       MERGE-SORT(A,q+1,r)
5       MERGE(A,p,q,r)

既然他们都使用了相同的划分策略,为什么快速排序忽略中间元素,因为从0q-1q+1r 没有包含q而mergesort有?

【问题讨论】:

  • 分区步骤将主元置于q,因此该值位于数组中的最终位置。
  • 注意这取决于分区算法。 Lomuto 不包括枢轴,而Hoare 包括其中一个分区中的枢轴。 Hoare - youtube 的变体不会移动枢轴或任何等于枢轴值的值。

标签: algorithm sorting quicksort mergesort


【解决方案1】:

快速排序 将所有小于枢轴的元素放在一侧,将所有大于枢轴的元素放在另一侧。在这一步之后,我们知道枢轴的最终位置将在这两者之间,这就是我们放置它的位置,所以我们不需要再次查看它。

因此我们可以在递归调用中排除枢轴元素。

Mergesort 只是选择中间位置,直到稍后才对该元素执行任何操作。无法保证该位置的元素已经在正确的位置,因此我们需要稍后再查看该元素。

因此我们必须在递归调用中包含中间元素。

【讨论】:

    【解决方案2】:

    这两种方法都利用了划分策略,但方式不同

    Mergesort(最常见的实现)递归地将数组划分为相等(如果可能)大小的部分,中间索引是固定位置(对于给定的数组长度)。递归调用完全处理数组的左右部分。

    Quicksort partition 子例程将枢轴元素放置在所需的(最终)位置(在大多数情况下,枢轴索引不在中间)。无需进一步处理此元素,递归调用会处理该元素之前和之后的片段。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-11
      • 1970-01-01
      • 2020-04-22
      • 2015-03-19
      • 2013-02-15
      • 1970-01-01
      • 2021-11-28
      相关资源
      最近更新 更多