简体   繁体   中英

Quicksort not sorting arrays with length 2

I am trying to implement a part of quicksort where I call a method called splitPoint. SplitPoint will use the first index of the array as the pivot value and the pivot will move to the center of the array. It will return the index of the new index of the pivot. However, If I have an array of length 2 and it is in descending, such as [2, 1], it fails to sort. The method works for everything else though. I think that if this does not work, my quicksort as a whole will not work.

 public int splitPoint(int[] a, int first, int last){

    int splitPoint = a[first];
    int low = first + 1;
    int high = last - 1;

    int temp; //holds the temp val for swapping values

    while(low < high){
        while(a[low] <= splitPoint && low != last && high > low){    
            low++;  
            //System.out.println("While loop 1 tracer");
            }
        while(a[high] > splitPoint && high >= first && high >= low){
            high--;
            //System.out.println("While loop 2 tracer");
        }

        if(low <= high){
            temp = a[low];
            a[low] = a[high];
            a[high] = temp;
            low++;
            high++;
        }

        System.out.println(Arrays.toString(a)); // tracer

    }

    a[first] = a[high];
    a[high] = splitPoint;

    return high;
}

Easy answer is to walk through your code.

Presuming your call looks like:

splitPoint({2, 1}, 0, 1);

int splitPoint = a[first];  // Will hold a value of 2.
int low = first + 1;   //low = 0 + 1 = 1.
int high = last - 1;  // high = 1 - 1 = 0.

int temp; //holds the temp val for swapping values

while(low < high)  //<== here. low = 1.  high = 0.  low > high, test is false--loop is NOT performed.

a[first] = a[high];  // a[0] = a[0] = 2.
a[high] = splitPoint;  //a[0] = 2

return high;  //returns 0.

So, in short, your problem is in your initialization of low and high.

If you check, you will see that for an input such as [5, 0, 3] it returns [0, 5, 3]. So there is a problem even for larger arrays.

A somewhat revised version of the code should work ok:

static int split(int[] array, final int first, final int last) {
    int low = first;
    int high = last;

    int splitPoint = first;
    while (low < high) {
        while (array[high] > array[low] && high > low) {
            high--;
        }
        while (array[low] <= array[high] && high > low) {
            low++;
        }
        if (low < high) {
            int tmp = array[low];
            array[low] = array[high];
            array[high] = tmp;
            if (low == splitPoint) {
                low++;
                splitPoint = high;
            } else {
                high--;
                splitPoint = low;
            }
        }
    }
    return splitPoint;
}

Example:

public static void main(String[] args) {
    int[] array = new int[]{5, 0, 3};
    System.out.println(split(array, 0, array.length - 1));
    System.out.println(Arrays.toString(array));
}

Output:

2
[3, 0, 5]

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