quick sort list in java

10.8k views Asked by At

I'm trying to practice quick sort list using java, I think this is correct but it shows "Exception in thread main..."

public class QuickSort {

  public static void sort(List<Integer> list) {
    sort(list, 0, list.size() - 1);
  }

  public static void sort(List<Integer> list, int from, int to) {
    if (list.size() <= 1) {
        return;
    }
    int pivot = from;
    int left = from + 1;
    int right = to;
    while (left < right) {
        while (list.get(pivot) >= list.get(left)) {
            left++;
        }
        while (list.get(pivot) <= list.get(right)) {
            right--;
        }
        if (left < right) {
            Collections.swap(list, left, right);
        }
    }
    Collections.swap(list, pivot, left - 1);
    sort(list, from, pivot - 1);
    sort(list, pivot + 1, to);
  }
}
2

There are 2 answers

3
David Pérez Cabrera On BEST ANSWER

Try with this:

public static void sort(List<Integer> list) {
    sort(list, 0, list.size() - 1);
}

public static void sort(List<Integer> list, int from, int to) {
    if (from < to) {
        int pivot = from;
        int left = from + 1;
        int right = to;
        int pivotValue = list.get(pivot);
        while (left <= right) {
            // left <= to -> limit protection
            while (left <= to && pivotValue >= list.get(left)) {
                left++;
            }
            // right > from -> limit protection
            while (right > from && pivotValue < list.get(right)) {
                right--;
            }
            if (left < right) {
                Collections.swap(list, left, right);
            }
        }
        Collections.swap(list, pivot, left - 1);
        sort(list, from, right - 1); // <-- pivot was wrong!
        sort(list, right + 1, to);   // <-- pivot was wrong!
    }
}
2
mazhar islam On

Your problem is here:

while (list.get(pivot) <= list.get(right)) {
        right--;
    }

As, In the worst case, say an already sorted list, your right-- will be negative.

Take a look the following code, this will give you idea:

public static void quicksort(List<Integer> list, int left, int right) {
    int q;
    if (right > left) {
        q = partition(list, left, right);
        // after ‘partition’
        // list[left..q-1] ≤ list[q] ≤ list[q+1..right]
        quicksort(list, left, q - 1);
        quicksort(list, q + 1, right);
    }
}

static int partition(List<Integer> list, int left, int right) {
    int P = list.get(left);
    int i = left;
    int j = right + 1;
    for (;;) { // infinite for-loop, break to exit
        while (list.get(++i) < P)
            if (i >= right)
                break;
        // Now, list[i]≥P
        while (list.get(--j) > P)
            if (j <= left)
                break;
        // Now, list[j]≤P
        if (i >= j)
            break; // break the for-loop
        else
            // swap(list[i],list[j]);
            Collections.swap(list, i, j);
    }
    if (j == left)
        return j;
    // swap (list[left],list[j]);
    Collections.swap(list, left, j);
    return j;
}

See a demo run here.