简体   繁体   中英

Can someone explain this quicksort algorithm to me?

I'm a little confused on quicksort. For example, with this algorithm taken from programcreek.com using the middle element as the pivot point:

public class QuickSort {
    public static void main(String[] args) {
        int[] x = { 9, 2, 4, 7, 3, 7, 10 };
        System.out.println(Arrays.toString(x));
 
        int low = 0;
        int high = x.length - 1;
 
        quickSort(x, low, high);
        System.out.println(Arrays.toString(x));
    }
 
    public static void quickSort(int[] arr, int low, int high) {
        if (arr == null || arr.length == 0)
            return;
 
        if (low >= high)
            return;
 
        // pick the pivot
        int middle = low + (high - low) / 2;
        int pivot = arr[middle];
 
        // make left < pivot and right > pivot
        int i = low, j = high;
        while (i <= j) {
            while (arr[i] < pivot) {
                i++;
            }
 
            while (arr[j] > pivot) {
                j--;
            }
 
            if (i <= j) {
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
                i++;
                j--;
            }
        }
 
        // recursively sort two sub parts
        if (low < j)
            quickSort(arr, low, j);
 
        if (high > i)
            quickSort(arr, i, high);
    }
}

Can someone explain the 2 recursive calls at the bottom, as well as why there is a need to create an i and j variable to copy the left and right markers.

Also, can someone explain the difference between a quicksort algorithm using the middle element vs using the first or last element as the pivot point? The code looks different in a sense that using the last / first element as the pivot point is usually written with a partition method instead of the code above.

Thanks!

Quicksort is based on divide and conquer method, first we take a pivot element and put all elements that are less than this pivot element on the left and all the elements that are greater than this pivot element on the right and after that we recursively perform the same thing on both sides of pivot for left side Quicksort(array,low,pivot-1) for right side Quicksort(array,low,pivot+1)

This was the answer of your first question

and now what is the difference between choosing the middle or first element as pivot so when we choose first element as pivot after sorting when i becomes greater than j we swap the pivot element(first element) with j so that the element that we chose as pivot comes at the place where all elements less than it comes at the left side and all elements greater than it comes it the right side.

and when we choose the middle element as pivot its already in the middle so there's no need to swap it.

This is a variation of Hoare partition scheme. The "classic" Hoare partition scheme increments i and decrements j before comparing to pivot. Both this example and the questions example include the partition logic in the main function.

void quickSort(int a[], size_t lo, size_t hi)
{
    int pivot = a[lo+(hi-lo)/2];
    int t;
    if(lo >= hi)
        return;
    size_t i = lo-1;
    size_t j = hi+1;
    while(1)
    {
        while (a[++i] < pivot);
        while (a[--j] > pivot);
        if (i >= j)
            break;
        t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
    QuickSort(a, lo, j);
    QuickSort(a, j+1, hi);
}

The questions code increments i and decrements j after comparing to pivot.

The partition logic splits up a partition so that the left side <= pivot, right side >= pivot. The pivot and elements equal to pivot can end up anywhere on either side, and may not end up in their sorted position until a base case of a sub-array of size 1 is reached.

The reason for using the middle element for pivot is that choosing the first or last element for pivot will result in worst case time complexity of O(n^2) if the array is already sorted or reverse sorted. The example in this answer will fail if the last element is used for pivot (but the questions example will not).

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