Quicksort and its simple optimization

       Quick sort is something that we will know when we enter the school in our freshman year, but I found that after I got to the university, I learned very hard, and it was all indoctrinated by others. Learning algorithms should be a process of thinking and exploration. It is not simply to AC this question and it is over. Then we worked so hard before college not to come to college to play, so we must learn to think and learn to explore in the future;

       First of all, today we are talking about quick sort. Here are three ways to write quick sort;

 ①The method of setting a flag, the two sentinels start walking from both ends respectively, the main code is as follows:

public static void quickSort(int[] arr,int l,int r){

        if ( l < r ){
            // random number of flags
            swap1(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int q = partition(arr ,l , r);
            quickSort(arr,l,q-1);
            quickSort(arr,q+1,r);
        }
    }

public static int partition(int[] arr,int l,int r){
        int p = arr[l];//Set the flag position
        int i = l;//left sentinel
        int j = r; // right sentinel
        while (i < j){
            while (arr[j] >= p && i < j){
                j--;
            }
            if (i<j){
                swap1(arr,i,j);
            }
            while (arr[i] <= p && i < j){
                i++;
            }
            if (i<j){
                swap1(arr,i,j);
            }
        }
        return i;
    }

 ②Set the rightmost bit as the flag bit, a sentinel compares from the leftmost one in turn, and divides the array into two areas. The code is as follows:

public static void quickSort2(int[] arr,int l,int r){

        if ( l < r ){
            // randomly generate flags
            swap1(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int q = partition2(arr,l,r);
            quickSort(arr,l,q-1);
            quickSort(arr,q+1,r);
        }
    }

public static int partition2(int[] arr,int l,int r){
        int i = l-1;
        int j = r;
        while (l < j){
            //Set the rightmost bit as the flag bit each time, which reduces the extra space
            if (arr[l]<=arr[r]){
                i++;
                swap1(arr,i,l);
                l++;
            }else{
                j--;
                swap1(arr,j,l);
            }
        }
        swap1(arr,j,r);
        return i+1;
    }

 ③ Divide the array into three parts, greater than area, less than area and equal area, which will reduce the number of comparisons, the code is as follows:

public static void quickSort1(int[] arr,int l,int r){

        if ( l < r ){
            swap1(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int[] q = partition1(arr,l,r);
            quickSort(arr,l,q[0]-1);
            quickSort(arr,q[0]+1,r);
        }
    }

 //The optimization algorithm for dividing the array, divides an array into three areas, greater than area, less than area and equal area
    public static int[] partition1(int[] arr,int l,int  r){
        int i = l-1;
        int j = r;
        while (l < j){
            //Set the rightmost one as a sentinel each time, which reduces the extra space
            if (arr[l]<arr[r]){
                swap1(arr,++i,l++);
            }else if (arr[l]>arr[r]){
                swap1(arr,--j,l);
            }else {
                l++;
            }
        }
        swap1(arr,j,r);
        return new int[] {i+1,j};
    }

 The complete code is as follows:

package study.tao.sort;

import java.util.Arrays;

/**
 * Created by Taoyongpan on 2017/11/13.
 * Quick sort and its optimization, we generally divide an array into two areas when quick sort
 * Greater than or equal to and less than two areas, what we have to do now is to say that an array is divided into three areas, greater than, equal to and less than three areas
 * The advantage of this is to put equal numbers in the middle every time, which will reduce the number of comparisons
 */
public class QuickSort {

    //Randomly generate an array with an array size of maxSize and a maximum value of maxValue
    public static int[] generateRandomArray(int maxSize,int maxValue){
        if (maxSize<=0){
            return null;
        }
        int[] arr = new int[(int)((maxSize+1)*Math.random())];

        for (int i = 0 ; i < arr.length ; i++){
            arr[i] = (int) ((maxValue+1)*Math.random());
        }
        return arr;
    }

    //output function of array
    public static void printArray(int[] arr){
        if (arr==null){
            return;
        }
        for (int j = 0 ; j < arr.length ; j++){
            System.out.print(arr[j]+" ");
        }
        System.out.println();
    }

    //copy function
    public static int[] copyArray(int[] arr){
        int[] res = new int[arr.length];
        if (arr == null){
            return null;
        }
        for (int i = 0 ; i < arr.length ; i++){
            res[i] = arr[i];
        }
        return res;
    }

    // swap function
    //bit operations are exchanged
    public static void swap(int[] arr,int i,int j){
        arr[i] = arr[i]^arr[j];
        arr[j] = arr[i]^arr[j];
        arr[i] = arr[i]^arr[j];
    }
    // swap function that requires extra space
    public static void swap1(int[] arr,int i,int j){
        int temp;
        temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    //system comparison function
    public static void arraySort(int[] arr){
        Arrays.sort(arr);
    }

    //Compare the result of the sorting function written by yourself and the sorting function of the system is equal
    public static boolean isEqual(int[] arr1,int[] arr2){
        if ((arr1 == null && arr2 !=null)||(arr1 !=null && arr2 ==null)||( arr1 == null && arr2 == null)){
            return false;
        }
        if (arr1.length != arr2.length){
            return false;
        }
        for (int i = 0 ; i <arr1.length;i++){
            if (arr1[i] != arr2[i]){
                return false;
            }
        }
        return true;
    }
    //quick sort
    public static void quickSort(int[] arr,int l,int r){

        if ( l < r ){
            swap1(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int q = partition(arr ,l , r);
            quickSort(arr,l,q-1);
            quickSort(arr,q+1,r);
        }
    }
    public static void quickSort1(int[] arr,int l,int r){

        if ( l < r ){
            swap1(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int[] q = partition1(arr,l,r);
            quickSort(arr,l,q[0]-1);
            quickSort(arr,q[0]+1,r);
        }
    }
    public static void quickSort2(int[] arr,int l,int r){

        if ( l < r ){
            swap1(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int q = partition2(arr,l,r);
            quickSort(arr,l,q-1);
            quickSort(arr,q+1,r);
        }
    }
    //Location function
    / / Divide the array, use the method of two sentinels
    public static int partition(int[] arr,int l,int r){
        int p = arr[l];//Set the sentinel position
        int i = l;
        int j = r;
        while (i < j){
            while (arr[j] >= p && i < j){
                j--;
            }
            if (i<j){
                swap1(arr,i,j);
            }
            while (arr[i] <= p && i < j){
                i++;
            }
            if (i<j){
                swap1(arr,i,j);
            }
        }
        return i;
    }
    //The optimization algorithm for dividing the array, divides an array into three areas, greater than area, less than area and equal area
    public static int[] partition1(int[] arr,int l,int  r){
        int i = l-1;
        int j = r;
        while (l < j){
            //Set the rightmost one as a sentinel each time, which reduces the extra space
            if (arr[l]<arr[r]){
                swap1(arr,++i,l++);
            }else if (arr[l]>arr[r]){
                swap1(arr,--j,l);
            }else {
                l++;
            }
        }
        swap1(arr,j,r);
        return new int[] {i+1,j};
    }
    //First-level optimization of dividing the array
    public static int partition2(int[] arr,int l,int r){
        int i = l-1;
        int j = r;
        while (l < j){
            //Set the rightmost one as a sentinel each time, which reduces the extra space
            if (arr[l]<=arr[r]){
                i++;
                swap1(arr,i,l);
                l++;
            }else{
                j--;
                swap1(arr,j,l);
            }
        }
        swap1(arr,j,r);
        return i+1;
    }
    // main function
    public static void main(String[] args){

        int maxSize = 100;
        int maxValue = 100;
        int maxTime = 3;
        boolean flag = true;
        int[] arr1 = generateRandomArray(maxSize,maxValue);//Randomly generate an array
        int[] arr2 = copyArray(arr1);//Copy the value in array 1 to arr2

        quickSort(arr1,0,arr1.length-1);
        arraySort(arr2);

        quickSort1(arr1,0,arr1.length-1);
        arraySort(arr2);

        quickSort2(arr1,0,arr1.length-1);
        arraySort(arr2);
        System.out.println(isEqual(arr1,arr2)?"succeed":"failed");
        printArray(arr1);
    }
}

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326586592&siteId=291194637