QuickSort Java实现问题

时间:2017-04-22 23:46:44

标签: java algorithm sorting quicksort

我试图将QuickSort算法作为大学的家庭作业,但我只是不明白我的代码中哪里有错误。我认为这是一个合乎逻辑的错误,我认为我错误地交换了我的枢轴。我真的可以使用一些帮助,谢谢你提前。有代码:

public class QuickSort {
    private int [] array;

    public QuickSort(int [] array){
        this.array = array;
    }

    public void sort(){
        partition(0, array.length - 1);
    }

    public void partition(int start, int end){
        if (end - start < 2){
            return;
        }
        int pivot_index = end;
        int i = start;
        int j = end - 1;
        while (i < j){
            //both elements are not in the right place
            if(array[i] > array[pivot_index] && array[j] <= array[pivot_index]){
                swap(array, i, j);
                i++;
                j--;
            }
            //the element on the left is not in place
            else if (array[i] > array[pivot_index] && array[j] > array[pivot_index]){
                j--;
            }
            //the element on the right is not in place
            else if (array[i] < array[pivot_index] && array[j] < array[pivot_index]){
                i++;
            }
            //both elements are in place
            else {
                i++;
                j--;
            }
        }
        if (array[i] > array[pivot_index]){
            swap(array, pivot_index, i);
            pivot_index = i;
        }
        partition(start, pivot_index - 1);
        partition(pivot_index + 1, end);
    }

    private static void swap(int [] tab, int index1, int index2){
        int temp = tab[index1];
        tab[index1] = tab[index2];
        tab[index2] = temp;
    }
}

1 个答案:

答案 0 :(得分:2)

解决方案一

想法是遍历数组以检查当前元素是否小于最后一个元素(枢轴),如果是,则交换第一个不是(index是lastSmaller + 1)。

private void partition(int start, int end) {
    if (start >= end) {
        return;
    }

    int lastSmallest = start - 1;
    for (int i = start; i < end; i++) {
        if (array[i] < array[end])
            swap(++lastSmallest, i);
    }

    swap(++lastSmallest, end);
    partition(start, lastSmallest - 1);
    partition(lastSmallest + 1, end);
}

解决方案二

我认为这是你想要实现的。遍历数组,跳过左右两侧的所有元素。将两者交换在错误的位置。

    private void partition(int start, int end) {
        if (end <= start) {
            return;
        }
        int k = end;
        int i = start;
        int j = end - 1;
        while (i < j) {
            // left is in place
            while (i < j && array[i] < array[k]) {
                i++;
            }
            // right is in place
            while (i < j && array[j] >= array[k]) {
                j--;
            }

            // both are not good
            if (i < j) {
                // swap
                int temp = array[i];
                array[i] = array[j];
                array[j] = temp;

                i++;
                j--;
            }
        }

        // swap left and pivot
        if (array[i] >= array[k]) {
            int temp = array[i];
            array[i] = array[k];
            array[k] = temp;
        }
        partition(start, i - 1);
        partition(i + 1, end);
}

您的解决方案不起作用的原因是当您发现两者都不到位时,您可以交换它们并继续对数组的其余部分进行分区。但是,您无法保证已交换的内容不违反规则。因此,您需要首先跳过两侧的所有元素然后交换。