有人可以向我解释这个版本的quicksort(在中间选择枢轴)吗?

时间:2019-06-06 18:27:48

标签: algorithm sorting quicksort

我最近重新访问了quicksort。我曾经通过从列表中选择最后一项或第一项来进行数据透视。但是另一个我碰到了这个片段,其中的片段是从中间拾取的。我知道枢轴的计算方式只会影响算法的性能。但我只是无法理解这种分区算法。

我想我了解分区算法的问题是,我认为它应该使结果数组像所有小于枢轴的项目都移到左侧,而所有大于枢轴的项目都移到左侧正确的。但是,这种分区算法并不总是能够实现这一目标。

private static void quickSort (int[] array, int left, int right) {
    int index = partition(array, left, right);

    //Sort left half
    if (left < index - 1)
        quickSort(array, left, index - 1);

    //Sort right half
    if (index < right)
        quickSort(array, index , right);
}

private static int partition (int array[], int left, int right) {
    int pivot = array[(left + right) / 2]; //Pick pivot point
    while (left <= right) {
        //Find element on left that should be on right
        while (array[left] < pivot)
            left++;

        //Find element on right that should be on left
        while (array[right] > pivot)
            right--;

        //Swap elements and move left and right indices
        if (left <= right) {
            int temp = array[left];
            array[left] = array[right];
            array[right] = temp;
            left++;
            right--;
        }
    }
    return left;
}

如果我给分区算法一个数组[1,0,-1,3,5,10,-5],则枢轴将为3,但是在分区之后,数组为[ 1, 0, -1, -5, 5, 10, 3 ]。我只是无法理解它,因为它看起来好像分区没有做任何有意义的事情。它没有将数组分成两半。

2 个答案:

答案 0 :(得分:1)

代码是Hoare分区方案的一种变体,其中每个分区步骤导致所有元素<枢轴位于所有元素的左侧>枢轴,但是元素==枢轴(包括枢轴本身)可以终止于左侧的任何位置或右分区,具体取决于数据模式。这就是为什么递归调用使用index-1和index的原因,因为返回的索引与枢轴不对应,因此不能将其排除在递归调用之外。

在示例情况下,在第一个分区步骤中,由于array [{0,1,2}] <枢轴,所以将左移至3,由于array [{6}]不是>,因此右未更改>枢纽,导致swap(array [3],array [6]),设定array [3] = -5和array [6] = 3(枢纽)。

答案 1 :(得分:0)

枢轴将移至右侧,而不会进行后续排序。左右指针已适当调整。从三个部分重新考虑该数组:左,右和枢轴。而不是

[ 1, 0, -1, -5, 5, 10, 3 ]

你有

[ 1, 0, -1, -5], [5, 10], [ 3 ]

left中的所有内容都小于枢轴; right中的所有内容都更大。