更改pivot计算位置会导致快速排序失败

u1ehiz5o  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(363)

在快速排序中,在排序条件之前对pivot求值会使算法工作,而使用其索引在条件内获取其值会使算法失败,尽管pivot索引是预先计算的,不应像左、右索引那样改变。
我不知道这里的问题是什么,以及这种变化是如何导致算法失败的,因为逻辑似乎没有变化,而是用相同的功能重新组织代码。
请检查下面的实现,解释的问题在方法中 partition 在评论部分:

import java.util.Arrays;

public class QuickSort {

    public static void main(String[] args) {
        int[] numbers = { 120, 10, 3, 8, 15, 22, 6, 2, 17, 60, 4, 13};
        System.out.println(Arrays.toString(numbers));
        quickSort(numbers);
        System.out.println(Arrays.toString(numbers));
    }

    private static void quickSort(int[] numbers) {
        quickSort(numbers, 0, numbers.length - 1);
    }

    private static void quickSort(int[] numbers, int left, int right) {
        if(left >= right) return;
        int index = partition(numbers, left, right);
        quickSort(numbers, left, index-1);
        quickSort(numbers, index, right);
    }

    private static int partition(int[] arr, int left, int right) {
        int pivotIndex = (left + right) / 2;
        int pivot = arr[pivotIndex];
        while(left <= right){
            // This won't work
            //while(arr[left] < arr[pivotIndex]) left++;
            //while(arr[right]> arr[pivotIndex]) right--;

            //This will work
            while(arr[left] < pivot) left++;
            while(arr[right]> pivot) right--;

            if(left <= right) {
                swap(arr, left, right);
                left++;
                right--;
            }
        }
        //swap(numbers, pivot, left);
        return left;
    }

    private static void swap(int[] arr, int left, int right) {
        int temp = arr[left];
        arr[left] = arr[right];
        arr[right] = temp;
    }
}
nkkqxpd9

nkkqxpd91#

因为pivot索引的值可以更改,
考虑一下这个非常简单的arr [7, 10, 4, 2] .
在第一次调用配分函数之后 left ,
在工作代码中,值为 3 阵列将 [7, 2, 4, 10] .
在非工作代码中,值为 2 阵列将 [7, 2, 4, 10] . 这显然是不正确的,因为索引中的左值 2 应小于索引处的值 2 . 这不是因为 7 小于 4 在左边。

相关问题