当前位置: 首页 > 知识库问答 >
问题:

为什么快速排序排除了中间元素,但合并排序包含了它?

扈翰
2023-03-14

我正在复习快速排序的实现(来自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包含?

共有2个答案

邬朗
2023-03-14

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

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

快速排序分区子例程将数据透视元素放置在所需(最终)位置(在大多数情况下,数据透视索引不在中间)。不需要进一步处理这个元素,递归调用处理该元素之前和之后的片段。

益稳
2023-03-14

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

因此,我们可以排除递归调用中的pivot元素。

Mergesort只选择中间位置,直到稍后才对该元素做任何事情。不能保证该位置的元素已经在正确的位置,因此我们需要稍后再次查看该元素。

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

 类似资料:
  • 我很难理解quicksort,大多数演示和解释都忽略了实际发生的事情(例如http://me.dt.in.th/page/quicksort/)。 维基百科说: 从数组中选择一个称为透视的元素。分区:对数组重新排序,使所有值小于pivot的元素都在pivot之前,而所有值大于pivot的元素都在pivot之后(相等的值可以从任何一个方向走)。分区后,枢轴处于其最终位置。这称为分区操作。将上述步骤递

  • 问题:Mergesort将一个数字列表分成两半,并对这两个数字进行递归调用。相反,您能在左半部分执行quicksort,在右半部分执行mergesort吗?如果是,则通过显示每个步骤来显示它将如何对下面的数字列表进行排序。如果没有,请解释为什么不能。 Iam应该使用MergeSort对数字列表进行排序。左半部分将使用快速排序进行排序? 我想出来了。安:是的,我们可以 使用mergeSort对数组的

  • 快速排序 from typing import List def quick_sort(arr: List, left, right) -> List: """ 快速排序是对冒泡排序的改进,核心思想是找到一个中值点pivot,然后将小于等于pivot的放在pivot的左边,大于pivot的放在右边,一直递归到无法拆分pivot点。 :param arr: :re

  • 在处理接近排序的数组时,哪种算法的快速排序或合并排序性能更好?为什么?我意识到,在这种情况下,其他算法可能会比这些算法表现得更好。

  • 问题内容: [http://jsperf.com/optimized-mergesort-versus- quicksort][1] 为什么这个半缓冲区合并排序的工作速度与quicksort一样快? QuickSort是: 就地虽然会占用递归(堆栈空间) 缓存友好 这一半缓冲区合并排序: 使用Buffer进行合并。 使用递归。 进行较少的比较。 我的问题是,在这种情况下,为什么半缓冲区合并排序与Q

  • 问题内容: 如何为Java实现并发的quicksort或mergesort算法? 我们在16(虚拟)核的Mac上遇到问题,其中只有一个核(!)使用默认的Java排序算法工作,而且很好的机器没有得到充分利用是不好的。因此,我们编写了自己的代码(我编写了代码),并且确实取得了不错的提速(我编写了多线程快速排序,由于其分区特性,它可以很好地并行化,但我也可以编写合并排序)……但是我的实现只能扩展最多4个