简体   繁体   中英

QuickSort Java implementation issue

I'm trying to implement a QuickSort algorithm as a homework at the university, but I just fail to understand where there is a mistake in my code. I suppose it's a logical mistake, I think I swap my pivot wrongly. I could really use some help, thank you in advance. There is the code:

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;
    }
}

Solution one

The idea is iterating through the array to check whether the current element is smaller than the last one (the pivot), if yes swap with the first one that is not (index is 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);
}

Solution two

I think this is what you want to implement. Iterate through the array, skip all the elements in good place on the left and right. Swap the two in wrong place.

    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);
}

The reason why your solution does not work is that when you find both are not in place, you swap them and continue to partition the rest of the array. However, you can not guarantee what you have swapped does not violate the rule. Therefore, you need to skip all the elements in place on both side first then swap.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM