具有Last Element Pivot的就地Quicksort?

时间:2016-09-13 16:53:11

标签: java algorithm sorting quicksort

我正在尝试实现In-Place Quicksort,最后一个元素作为我的支点。下面附有我的代码

public static void main(String[] args){
        int[] input = {3,2,4,6,10,1,9,7,5};
        quickSort(input, 0, input.length-1);
    }
    public static void swap(int[] array, int i, int j) {
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }

    public static int partition(int arr[], int left, int right) {
        int pivot = arr[right];
        int high = right-1;

        while(left < high){
            while(arr[left] < pivot){
                left++;
            }
            while(arr[high] > pivot){
                high--;
            }
            swap(arr,left, high);
            left++;
            high--;
        }
        swap(arr, left, pivot);
        System.out.println(Arrays.toString(arr));
        return left;
    }

    public static void quickSort(int arr[], int left, int right) {
        int index = partition(arr, left, right);
        quickSort(arr, left, index - 1);
        quickSort(arr, index, right);
    }

出于某种原因,我的代码给了我一个IndexOutOfBounds Exception,它没有准确地对数组进行排序。我不知道为什么我会收到这个错误。

如果我理解正确,我们应该将最后一个元素作为我们的支点。然后,我们向左迭代左指针,直到找到一个大于枢轴的元素。在那之后,我们从右侧(继续向左移动)做同样的事情,直到我们发现一个小于枢轴的元素。然后我们交换这些元素并继续做同样的事情。

最后,当左/右指针相同时,我们将中心值与我们的枢轴交换。

这是正确的思考方式吗?如果是这样,我的代码有什么错误?任何帮助将不胜感激

2 个答案:

答案 0 :(得分:3)

一些错误:

  • left < high个检查添加到内部循环中。每次修改左侧或右侧时都应该检查它。

  • 检查arr[high] >= pivot而非arr[high] > pivot

  • swap(arr, left, pivot);错了。您应该使用位置而不是值来交换左侧枢轴。它应该是swap(arr, left, right);

  • 您应该在快速排序方法中查看left < right

修复这些错误后,您的代码应如下所示:

    public static void main(String[] args){
        int[] input = {3,2,4,6,10,1,9,7,5};
        quickSort(input, 0, input.length-1);
    }
    public static void swap(int[] array, int i, int j) {
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }

    public static int partition(int arr[], int left, int right) {
        int pivot = arr[right];
        int high = right;

        while(left < high){
            while(left < high && arr[left] < pivot){
                left++;
            }
            while(left < high && arr[high] >= pivot){
                high--;
            }
            swap(arr,left, high);
        }
        swap(arr, left, right);
        System.out.println( Arrays.toString(arr));
        return left;
    }

    public static void quickSort(int arr[], int left, int right) {
        if( left < right)
        {
            int index = partition(arr, left, right);
            quickSort(arr, left, index - 1);
            quickSort(arr, index, right);
        }
    }

答案 1 :(得分:0)

在假设最终数组元素是最小元素的情况下跟踪此代码。调整高的循环将连续递减高,因为每个其他数组元素都比枢轴大,所以最终高位将从数组的前面掉落,导致您的越界访问。

要解决此问题,请在该循环中添加另一个检查,以确保您没有高横向和左横。然后,您可能需要在之后添加一些额外的逻辑来处理这种情况。