从概念上理解快速排序

时间:2013-11-18 23:31:14

标签: java recursion

我正在尝试将Quick Sort工作可视化。主要是,我试图了解它的分区部分。我将发布以下代码:

public int paritionIt(int left, int right, long pivot){
    leftPtr = left - 1;
    rightPtr = right + 1;

    while (true) {
        while (leftPtr < right && Array[++leftPtr] < pivot);
        while (rightPtr > left && Array[--rightPtr] > pivot);
        if (leftPtr <= rightPtr)
            break;
        else
            swap(leftPtr, rightPtr);
    } //end while loop
    return leftPtr;
}

我的最终问题是:为什么我们要返回leftPtr?我觉得这样做不对......快速排序算法使用递归,如下所示:

public void recQuicksort(int left, int right){
    if(left - right <= 0)
        return 0;
    else{
        long pivot = array[right];
        int partition = partitionIt(left, right, pivot);
        recQuicksort(left, partition -1);
        recQuicksort(partition + 1, right);
    }
}

我只是在努力构思这个问题时遇到了困难。

2 个答案:

答案 0 :(得分:3)

这个特定版本的分区的工作是重新排序列表,以便所有元素不大于枢轴出现在所有元素之前不小于枢轴。 (这意味着与pivot相等的元素可以分散在任何地方。此外,它必须返回第二个子列表开头的索引。

许多订单都可以满足这一要求。对于一个排序,多个返回值可能有效。这不会影响Quicksort的正常运行,所以不用担心。

对于你的示例数据(3,9,4,7),第一遍将以left = 1,right = 3停止,因此它将交换7和9以产生(3,7,4,9)。接下来它将以left = 3和right = 2停止,这会导致从另一个循环中断。返回值为3.这是正确的,因为它是一步过去初始子数组的末尾,现在完全小于或等于数据透视。

但是对于这个版本的分区,quicksort有一个bug。它应该是:

public void recQuicksort(int left, int right) {
  if (left < right) {
    long pivot = array[right];
    int partition = partitionIt(left, right, pivot);
    recQuicksort(left, partition - 1);
    recQuicksort(partition, right);
  }
}

答案 1 :(得分:0)

我开发了一个网页,用于显示快速排序的过程,当前版本支持最后一项作为支点,我认为该页面将帮助您了解快速排序。quick sort

要显示数据集的快速排序工作(1,2,3,4,5),您只需输入 1 2 3 4 5 并按Enter键。要显示最佳情况,请输入 b5 ,数字 5 表示重复深度。要显示平均情况,请输入 r1..10 r 表示随机 1..10 表示 1 2 3 4 5 6 7 8 9 10 的随机排列数据集。

这是一个最好的案例: enter image description here

最坏的情况:

enter image description here

平均情况:

enter image description here