C++ 快速排序w/quot;中位数为三“;轴心选择:理解过程

C++ 快速排序w/quot;中位数为三“;轴心选择:理解过程,c++,quicksort,partitioning,multiple-languages,C++,Quicksort,Partitioning,Multiple Languages,在我们的课堂上,我们将学习快速排序(使用数组)。我一直在碰壁,想弄明白他们希望我们的快速排序任务如何使用“三个中间值”轴心选择方法。我只需要一个高层次的解释它是如何运作的。我们的文本没有帮助,我很难在谷歌上找到一个清晰的解释 这是我认为到目前为止能够理解的: “三个中位数”函数取索引0(第一个)、数组结束索引(最后一个)和(索引0+数组结束索引)/2(中间)中的元素。计算具有这3个中间值的指数。返回相应的索引 功能参数如下: /* @param left * the left bou

在我们的课堂上,我们将学习快速排序(使用数组)。我一直在碰壁,想弄明白他们希望我们的快速排序任务如何使用“三个中间值”轴心选择方法。我只需要一个高层次的解释它是如何运作的。我们的文本没有帮助,我很难在谷歌上找到一个清晰的解释

这是我认为到目前为止能够理解的:

“三个中位数”函数取
索引0
(第一个)、
数组结束索引
(最后一个)和
(索引0+数组结束索引)/2
(中间)中的元素。计算具有这3个中间值的指数。返回相应的索引

功能参数如下:

/* @param left
*       the left boundary for the subarray from which to find a pivot
* @param right
*       the right boundary for the subarray from which to find a pivot
* @return
*       the index of the pivot (middle index); -1 if provided with invalid input
*/
int QS::medianOfThree(int left, int right){}
/* @param left
*       the left boundary for the subarray to partition
* @param right
*       the right boundary for the subarray to partition
* @param pivotIndex
*       the index of the pivot in the subarray
* @return
*       the pivot's ending index after the partition completes; -1 if
*       provided with bad input
*/
int QS::partition(int left, int right, int pivotIndex){}
然后,在“分区”函数中,其索引与“三个中位数”函数返回的索引匹配的数字作为轴心。我的任务指出,为了继续对数组进行分区,枢轴必须位于左右边界之间。问题是,我们的“三个中位数”函数返回了三个索引中的一个:第一个、中间或最后一个索引。这三个指数中只有一个(中间)可能“介于”任何东西之间

功能参数如下:

/* @param left
*       the left boundary for the subarray from which to find a pivot
* @param right
*       the right boundary for the subarray from which to find a pivot
* @return
*       the index of the pivot (middle index); -1 if provided with invalid input
*/
int QS::medianOfThree(int left, int right){}
/* @param left
*       the left boundary for the subarray to partition
* @param right
*       the right boundary for the subarray to partition
* @param pivotIndex
*       the index of the pivot in the subarray
* @return
*       the pivot's ending index after the partition completes; -1 if
*       provided with bad input
*/
int QS::partition(int left, int right, int pivotIndex){}
我误解了什么

以下是功能的完整说明

/*
* sortAll()
*
* Sorts elements of the array.  After this function is called, every
* element in the array is less than or equal its successor.
*
* Does nothing if the array is empty.
*/
void QS::sortAll(){}

/*
* medianOfThree()
*
* The median of three pivot selection has two parts:
*
* 1) Calculates the middle index by averaging the given left and right indices:
*
* middle = (left + right)/2
*
* 2) Then bubble-sorts the values at the left, middle, and right indices.
*
* After this method is called, data[left] <= data[middle] <= data[right].
* The middle index will be returned.
*
* Returns -1 if the array is empty, if either of the given integers
* is out of bounds, or if the left index is not less than the right
* index.
*
* @param left
*       the left boundary for the subarray from which to find a pivot
* @param right
*       the right boundary for the subarray from which to find a pivot
* @return
*       the index of the pivot (middle index); -1 if provided with invalid input
*/
int QS::medianOfThree(int left, int right){}

/*
* Partitions a subarray around a pivot value selected according to
* median-of-three pivot selection.
*
* The values which are smaller than the pivot should be placed to the left
* of the pivot; the values which are larger than the pivot should be placed
* to the right of the pivot.
*
* Returns -1 if the array is null, if either of the given integers is out of
* bounds, or if the first integer is not less than the second integer, OR IF THE
* PIVOT IS NOT BETWEEN THE TWO BOUNDARIES.
*
* @param left
*       the left boundary for the subarray to partition
* @param right
*       the right boundary for the subarray to partition
* @param pivotIndex
*       the index of the pivot in the subarray
* @return
*       the pivot's ending index after the partition completes; -1 if
*       provided with bad input
*/
int QS::partition(int left, int right, int pivotIndex){}
/*
*索塔尔
*
*对数组的元素进行排序。调用此函数后,每个
*数组中的元素小于或等于其后续元素。
*
*如果数组为空,则不执行任何操作。
*/
void QS::sortAll(){}
/*
*medianOfThree()
*
*三轴选择的中间值有两部分:
*
*1)通过平均给定的左指数和右指数计算中间指数:
*
*中间=(左+右)/2
*
*2)然后气泡对左、中、右索引处的值进行排序。
*

*调用此方法后,
medianoftree
的文档中的数据[left]显示:

* 2) Then bubble-sorts the values at the left, middle, and right indices.
*
* After this method is called, data[left] <= data[middle] <= data[right].
* The middle index will be returned.
*2)然后气泡对左、中、右索引处的值进行排序。
*

*调用此方法后,
medianoftree
的文档中的数据[left]显示:

* 2) Then bubble-sorts the values at the left, middle, and right indices.
*
* After this method is called, data[left] <= data[middle] <= data[right].
* The middle index will be returned.
*2)然后气泡对左、中、右索引处的值进行排序。
*
*调用此方法后,data[left]计算“中位数3”是一种在数组中获得伪中位数元素的方法,并使该索引等于分区。这是一种简单的方法,可以粗略估计阵列的中值,从而获得更好的性能

为什么这会有用?因为从理论上讲,您希望将此分区值作为数组的真实中间值,因此当您对该数组进行快速排序时,pivot会将此数组平均分割,并启用quick sort提供的良好的O(NlogN)排序时间

示例:您的阵列是:

[5,3,1,7,9]
三者的中位数分别为5、1和9。中值明显为5,所以这是我们希望考虑的快速排序函数的枢轴值。接下来可以做的是将此索引与最后一个索引交换,然后获取

[9,3,1,7,5]
现在,我们尝试在中间左侧显示所有小于5的值,在中间右侧显示所有大于5的值。我们现在得到

[1,3,7,9,5]
将最后一个元素(存储分区值的位置)与中间的元素交换

[1,3,5,9,7]
这就是使用3的中间部分的想法。想象一下,如果我们的分区是1或9。您可以想象,我们得到的这个数组不是快速排序的好例子

计算“三个中位数”是一种在数组中获得伪中位数元素的方法,并使该索引等于分区。这是一种简单的方法,可以粗略估计阵列的中值,从而获得更好的性能

为什么这会有用?因为从理论上讲,您希望将此分区值作为数组的真实中间值,因此当您对该数组进行快速排序时,pivot会将此数组平均分割,并启用quick sort提供的良好的O(NlogN)排序时间

示例:您的阵列是:

[5,3,1,7,9]
三者的中位数分别为5、1和9。中值明显为5,所以这是我们希望考虑的快速排序函数的枢轴值。接下来可以做的是将此索引与最后一个索引交换,然后获取

[9,3,1,7,5]
现在,我们尝试在中间左侧显示所有小于5的值,在中间右侧显示所有大于5的值。我们现在得到

[1,3,7,9,5]
将最后一个元素(存储分区值的位置)与中间的元素交换

[1,3,5,9,7]

这就是使用3的中间部分的想法。想象一下,如果我们的分区是1或9。您可以想象,我们得到的这个数组不是快速排序的好例子

首先从理解快速排序开始,然后是三个中间值

要执行快速排序,请执行以下操作:

  • 从正在排序的数组中选择一个项目(任何项目都可以,但我们将返回哪个项目是最好的)
  • 对数组重新排序,使所有小于您拾取的项目在数组中位于它之前,而所有大于它的项目位于它之后
  • 递归地对拾取的项目前后的集合执行上述操作
  • 步骤2称为“分区操作”。考虑以下情况:

    3 2 8 4 1 9 5 7 6
    
    现在假设您选择了这些数字中的第一个作为轴心元素(我们在步骤1中选择的那个)。在应用步骤2后,我们最终得到如下结果:

    2 1 3 4 8 9 5 7 6
    
    3
    现在位于正确的位置,并且每个元素都位于正确的一侧。如果我们现在对左侧进行排序,我们将得到:

    1 2 3 4 8 9 5 7 6.
    
    5 7 6 8 9.
    

    现在,让我们考虑一下右边的元素:

    4 8 9 5 7 6.
    
    如果我们选择
    4
    作为下一步的轴心,我们最终什么也没有改变,因为它一开始就处于正确的位置。它左边的元素集是空的,所以这里不做任何事情。我们现在需要对集合进行排序:

    8 9 5 7 6.
    
    如果我们用8作为支点