Question

public class QuickSort {
    public static void sort(int[] a) {
        StdRandom.shuffle(a);
        sort(a, 0, a.length - 1);
    }

    private static void sort(int[] a, int left, int right) {
        if (right <= left) {
            return;
        }
        int j = partition(a, left, right);      
        sort(a, left, j - 1);
        sort(a, j + 1, right);
    }

    private static int partition(int[] a, int left, int right) {
        int i = left;
        int j = right+1;
        int pivot = a[left];
        while (true) {
            while (a[++i] < pivot) {
                if (i == right) {
                    break;
                }
            }
            while (a[--j] > pivot) {
                if (j == left) {
                    break;
                }
            }
            if (i >= j) {
                break;
            }
            swap(a, i, j);
        }
        swap(a, left, j);
        return j;
    }

    private static void swap(int[] a, int i, int j) {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;

    }

    public static void main(String[] args) {
        int[] a = { 5, 3, 1, 34, 43, 5454};
        QuickSort.sort(a);
        show(a);

    }

    private static void show(int[] a) {
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + " ");
        }

    }
}

in this example, the int j = right+1 starts outside the array, so then we decrement by a[--j]

When I change it to int j = right and decrement by a[j--] the output is not the same. Probably something simple but been confused about for the past hour. I don't get why we don't just decrement starting at the last index of the array such as:

{4,3,6,1,9}

int j = right 

so j = array[4] then we say while... array[4--] which would turn into j=array[3] right?

isn't this the same thing: right+1 and --j and to right and j--

Was it helpful?

Solution

The lines:

while (a[--j] > pivot) {
    if (j == left) {
        break;
    }
}

Expect the two values of j to be the same. If you change it to

while (a[j--] > pivot) {
    if (j == left) {
        break;
    }
}

The first referenced j, a[j--] will be one higher then the next j, j == left

If you wanted to make the change, you would have to change it to:

while (a[j--] > pivot) {
    if (j+1 == left) { //adding one back in
        break;
    }
}

My personal opinion is that the code was cleaner before, since starting one outside a range is common and understandable. Adding one back is is 'fiddly' and will make everyone question whether it is correct.

The clearest way to make your change might be:

while (a[j] > pivot) {
    if (j == left) {
        break;
    }
    j--; // waiting until the end to decrement
}

I would consider that pretty clean, and preferable to the original because you start with int j = right.

OTHER TIPS

The value of j is compared against in other places in the loop. If the counter started with j = right, after decrementing j with either --j or j-- the value of j at those points will not be the same as if you started with j = right+1

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top