Divide and Conquer Idea-Understanding Quick Sort

principle

Quick sort vs merge sort, the former is based on numerical size division, and the latter is based on index division.

Quick sort does not require additional storage space, which makes it better than merge sort, because merge sort requires an extra double the storage space to store the sorted array.

Quick sort finds a pivot from the array, puts the ones smaller than piovt on the left, and puts the ones larger than pivot on the right. The pseudo code is as follows:

QuickSort(A):
    S− ={};S+ ={};//s-存小于,s+存大于
    Choose a pivot A[j];//随机选择
    
    for i=0 to n−1 do
        Put A[i] in S− if A[i] < A[j];
        Put A[i] in S+ if A[i] ≥ A[j];
    
    QuickSort(S+);
    QuickSort(S−);
    
    Output S−, then A[j], then S+;

time complexity

  • Estimate time complexity

Consider two extreme cases

  1. Best case: pivot selects the median every time

T (n) = 2 T (n 2) + O (n) = O (nlogn) T (n) = 2T (\ frac {n} {2}) + O (n) = O (nlogn) T(n)=2 T (2n)+O ( n )=O ( n l o g n )

  1. Worst-case scenario: Pivot selects the topmost number every time

T (n) = T (n - 1) + O (n) = O (n 2) T (n) = T (n-1) + O (n) = O (n ^ 2) T(n)=T(n1)+O ( n )=O ( n2)

  1. General situation: a high probability of selecting the middle number

T (n) = O (nlogn) T (n) = O (nlogn) T(n)=O ( n l o g n )

Suppose that when pivot is taken, the division ratio is 3:1. Since the additional cost of each division is O(n), the total time complexity is O(nlog_\frac(4)(3)n)=O(nlogn) , The same complexity as the best case. Similarly, the division of 8:1 and 100:1 also has O(nlog_\frac{9}{8}n)=O(nlog_\frac{101}{100}n )=O(nlogn)

pivot selection

From the above analysis, we can see that the quality of quick sort is related to pivot. In order to make the selection of pivot closer to the middle, there are several ideas to improve the division effect:

  1. Randomly sample and select three elements, and take the median as pivot
  2. Take the first, middle and last three elements, and take the median as pivot
  3. Re-divide until the appropriate pivot is selected: add a layer of loop, after each layer is divided, judge ∣S−∣≥n/4,∣S+∣≥n/4|, whether the two conditions are satisfied, if not, then re Select, otherwise exit the loop

Implementation code

public class QuickSort {
    
    
    //数组内的数换位
    private void swap(int[]A,int s,int r){
    
    
        if(s!=r){
    
    
            A[s] += A[r];
            A[r] = A[s] - A[r];
            A[s] = A[s] - A[r];
        }
    }

    //选pivot,写成接口方便修改
    private int findpivot(int[] A,int l,int r){
    
    
        return (l+r)/2;
    }

    //划分
    private int partition(int[] A,int l,int r,int p){
    
    
        do{
    
    
            while(A[l]<p) {
    
     l++; }
            while((l<r) && A[r]>=p) {
    
     r--; }
            swap(A,l,r);
        }while (l<r);
        return l;
    }

    private void quicksort(int[] A,int l,int r){
    
    
        if(l<r) {
    
    
            int p = findpivot(A, l, r);
            swap(A, p, r);
            int k = partition(A, l, r - 1, A[r]);
            swap(A, k, r);
            quicksort(A, l, k - 1);
            quicksort(A, k + 1, r);
        }
    }

    public static void main(String[] args) {
    
    
        int[] data = new int[]{
    
    4,5,7,6,2,3,1,8};
        QuickSort test = new QuickSort();
        test.quicksort(data,0,data.length-1);
        for(int i=0;i<data.length;i++){
    
    
            System.out.println(data[i]);
        }

    }
}

Guess you like

Origin blog.csdn.net/qq_32505207/article/details/106261705