Java's seven major sorting methods: quick sort (three methods including optimization methods)

(1) Basic idea

Take any element in the sequence of elements to be sorted as the benchmark value, and divide the set to be sorted into two subsequences according to the sorting code. All elements in the left subsequence are less than the benchmark value, and all elements in the right subsequence are greater than the benchmark value. Then the process is repeated for the left and right subsequences until all elements are arranged in the corresponding positions.

(2) Code implementation

1) Digging method

After dividing, recurse left and right. When array[right] >= tmp is encountered, exchange array[left] and array[right];

 By analogy, the correct ordering is finally obtained. 

 public static int partition(int[] array,int left,int right){
        int tmp =array[left];
        while (left < right) {
            while (left < right && array[right] >= tmp){
                right--;
            }
            array[left] = array[right];
            while (left < right && array[left] <= tmp){
                left++;
            }
            array[right] = array[left];
        }
        array[left] = tmp;
        return left;
    }
    public static void quickSort(int[] array) {
        quick(array,0,array.length-1);
    }
    public static void quick(int[] array,int start,int end) {
        if (start >= end) {
            return;
        }
        //先划分,再左右递归
        int pivot = partition(array,start,end);
        quick(array,start,pivot-1);
        quick(array,pivot+1,end);
    }

2) Hoare method

When right finds a smaller value than the baseline and left finds a larger value than the baseline, their values ​​are swapped.

public static int partition2(int[] array,int left,int right){
        int tmp =array[left];
        int i = left;
        while (left < right) {
            while (left < right && array[right] >= tmp){
                right--;
            }
            while (left < right && array[left] <= tmp){
                left++;
            }
            swap(array,left,right);
        }
        //相遇之后
        swap(array,left,i);
        return left;
 }

The swap method is a swap method. I have written about it in my previous article, so I won’t write about it here. You can read the previous article if necessary.

3) Front and back pointer method (just understand it)

Writing method 1:

private static int partition(int[] array, int left, int right) {
int prev = left ;
int cur = left+1;
while (cur <= right) {
if(array[cur] < array[left] && array[++prev] != array[cur]) {
swap(array,cur,prev);
}
cur++;
}
swap(array,prev,left);
return prev;
}

Writing method 2:

private static int partition(int[] array, int left, int right) {
int d = left + 1;
int pivot = array[left];
for (int i = left + 1; i <= right; i++) {
if (array[i] < pivot) {
swap(array, i, d);
d++;
}
}
swap(array, d - 1, left);
return d - 1;
}

4) Non-recursive implementation of quick sort

public static void quickSort(int[] array) {
        Deque<Integer> stack = new LinkedList<>();
        int left = 0;
        int right = array.length-1;
        int pivot = partition(array,left,right);
        if (pivot > left+1) {
            stack.push(left);
            stack.push(pivot-1);
        }
        if (pivot < right-1) {
            stack.push(pivot+1);
            stack.push(right);
        }
        while (!stack.isEmpty()) {
            right = stack.pop();
            left = stack.pop();
            pivot = partition(array,left,right);
            if (pivot > left+1) {
                stack.push(left);
                stack.push(pivot-1);
            }
            if (pivot < right-1) {
                stack.push(pivot+1);
                stack.push(right);
            }
        }
    }

(3) Feature summary

1. The overall comprehensive performance and usage scenarios of quick sort are relatively good;

2. Time complexity: O(N*logN) Space complexity: O(logN);

3. Stability: unstable.

(4) Optimization of quick sort

When there are too many elements that need to be sorted, it is very important for us to select the basis. Therefore, we adopt the three-number method to select the appropriate basis.

The method of finding the middle of three numbers: choose the one that is neither the largest nor the smallest among three numbers.

private static int midTree(int[] array,int left,int right) {
        int mid = (left+right)/2;
        if (array[left] < array[right]) {
            if (array[mid] < array[left]) {
                return left;
            } else if(array[mid] > array[right]) {
                return right;
            } else {
                return mid;
            }
        } else {
            if (array[mid] < array[right]) {
                return right;
            } else if(array[mid] > array[left]) {
                return left;
            } else {
                return mid;
            }
        }
    }

If you encounter any questions, please add them in the comment area!

Guess you like

Origin blog.csdn.net/m0_56911648/article/details/130856402