Algorithm quick sort (random optimization)

Algorithm quick sort

@author:Jingdai
@date:2020.10.28

I swipe LeetCode today, and found that I forgot the quick sort I learned before. Now record it, I hope I won’t forget it again in the future.

Introduction

Quick sort, that is, quick sort. Well, nothing to say, just look at the train of thought.

Ideas

The idea in one sentence is to determine a number in the array pivot, and then put all the numbers less than it on the left of it, and put all the numbers greater than it on the right. Then recursively call the same algorithm on the left sub-array and the right sub-array to complete the sorting, see the following code snippet.

public static void quickSort(int[] array, int left, int right) {
     
     
    
    if (left >= right) {
     
     
        return;
    }

    int pivot = positionAndGetPivot(array, left, right);
    quickSort(array, left, pivot - 1);
    quickSort(array, pivot + 1, right);
}

Looking at the above code, you will find that, in fact, the main problem is to select one pivot, and put the number smaller than it on the left side, and the number larger than it on the right side. That choice as to which number pivotit? For simplicity, where the first selected as the leftmost array pivot, then two pointer variables leftand rightleftmost subscript of an array and recording the rightmost index. As shown, starting with the right to find than a pivotsmall number on the number to move it to the left and then from left than to find a pivotlarge number of the number, it will be moved to the right, until the cycle has been leftequal right. Then pivotput the values leftcan be (a position at this time leftand rightare equal). In fact, the whole process is a bit like algorithm swaps two variables values, you need to use an intermediate variable, but here with a record variable pivotvalue, and then the right place to find a number of its position on the right side of that position and can put a number of other and then look for a number put on the right from the left, until leftand rightequal, then the original intermediate variable that is recorded in pivotthe value placed in this position.

Insert picture description here

Look at the code snippet below.

public static int positionAndGetPivot(int[] array, int left, int right) {
     
     
    int pivotValue = array[left];
    while (left < right) {
     
     
        while (left < right && array[right] >= pivotValue) {
     
     
            right --;
        }
        array[left] = array[right];
        while (left < right && array[left] <= pivotValue) {
     
     
            left ++;
        }
        array[right] = array[left];
    }
    array[left] = pivotValue;
    return left;
}

But there is a little problem with the above code. When the randomness of the numbers in the array is not good, the efficiency of fast sorting is not very ideal. Here we can manually introduce randomness. Each time we select the leftmost number in the array as above pivot, we can choose randomly pivot, so as to prevent efficiency problems caused by insufficient randomness of the array. It's very simple, leftand rightrandomly selects one as the index pivot, then the selected number of array[left]exchanged like, see the following code snippet.

public static int positionAndGetPivot(int[] array, int left, int right) {
     
     

    Random r = new Random();
    int pivotIndex = r.nextInt(right - left + 1) + left;
    int pivotValue = array[pivotIndex];
    array[pivotIndex] = array[left];

    while (left < right) {
     
     
        while (left < right && array[right] >= pivotValue) {
     
     
            right --;
        }
        array[left] = array[right];
        while (left < right && array[left] <= pivotValue) {
     
     
            left ++;
        }
        array[right] = array[left];
    }
    array[left] = pivotValue;
    return left;
}

Completion of pivotthe function of the position selected, then recursively call this algorithm can be completed quickly lined up. The complete code is as follows.

Code

public static void main(String[] args){
     
     

    int[] array = {
     
     4, 5, 9, 2, 1, 4, 1, 3, 5, 6, 7};
    quickSort(array);
    System.out.println(Arrays.toString(array));

}

public static void quickSort(int[] array) {
     
     
    quickSort(array, 0, array.length-1);
}

public static void quickSort(int[] array, int left, int right) {
     
     

    if (left >= right) {
     
     
        return;
    }

    int pivot = positionAndGetPivot(array, left, right);
    quickSort(array, left, pivot - 1);
    quickSort(array, pivot + 1, right);
}

public static int positionAndGetPivot(int[] array, int left, int right) {
     
     

    Random r = new Random();
    int pivotIndex = r.nextInt(right - left + 1) + left;
    int pivotValue = array[pivotIndex];
    array[pivotIndex] = array[left];

    while (left < right) {
     
     
        while (left < right && array[right] >= pivotValue) {
     
     
            right --;
        }
        array[left] = array[right];
        while (left < right && array[left] <= pivotValue) {
     
     
            left ++;
        }
        array[right] = array[left];
    }
    array[left] = pivotValue;
    return left;
}

Guess you like

Origin blog.csdn.net/qq_41512783/article/details/109326468