[java data structure] quick sort implementation

Insert picture description here
Welcome everyone~
Let's learn together and make progress together~

1. The principle of fast sorting : generally divided into three steps:
1. Select a number from the interval to be sorted as the reference value (usually choose the leftmost number)
2. Partition: Traverse the entire range to be sorted, and it will be smaller than the reference value (Can include equal) put it to the left of the reference value, and put the one that is larger than the reference value (can include equal) to the right of the reference value.
3. Adopt the idea of ​​divide and conquer, treat the left and right cells in the same way, until the length between the cells is <=1, then exit the comparison.

Insert picture description here
Take the array [3,5,2,7,9,4,8] as an example, the process of fast sorting:
Insert picture description here
Second, the process of comparison is the process of Partition.
There are three methods for java to realize the part of fast sorting :
1 Hoare method
2 .Digging method
3.

The idea of ​​Hoare method before and after traversal method :
Insert picture description here

The idea of ​​the digging method: the basic idea is the same as the Hoare method, but no more exchanges, but direct assignment (digging + filling)

The idea of ​​traversal before and after: traverse from the second number, find the number smaller (or larger) than the first number, and then exchange with the first number. The idea is also relatively simple, and everyone can understand it by looking at the code.

3. Performance analysis:
time complexity : best O(n log(n)) worst O(n^2) average complexity: O(n log(n))
space complexity : best: O(n log (n)) Worst: O(n) Average: O(n log(n))
Stability : Unstable

Fourth, on the optimization method of fast queue: The
general interviewer considers these aspects when asking.
1. Digging in the paitition section (optimization for small details)
2. When the number of comparisons is relatively small, the quick sorting is not the fastest; (when the number in the interval is lower than a certain threshold (16), use interpolation Row)
3. Optimize the way to select a special number-----Now select the leftmost number as the comparison value
a. Randomly select b. Select a few numbers, and pick the size value in the middle (the third number is selected)
4. Treat equal values ​​specially

Five, the code implementation part of quick sort : (three methods) are to achieve sorting from small to large

public class Hoare {
    
    
    public static void quickSort(long[] array) {
    
    
        quickSortInternal(array, 0, array.length - 1);
    }

    // 区间是 [lowIndex, highIndex]
    private static void quickSortInternal(long[] array,int lowIndex,int highIndex) {
    
    
        // 由于是闭区间,所以,区间内个个数需要加个 1
        int size = highIndex - lowIndex + 1;
        if (size <= 1) {
    
    
            return;
        }

        // 选择其中一个数(选最左边的) —— array[lowIndex]
        // 执行 partition,小的放左,大的放右
        // keyIndex 是经过 partition 之后,选出来的数最终所在下标
        int keyIndex = partition(array, lowIndex, highIndex);
        // 分别对左右区间进行相同的处理 —— 递归方法
        quickSortInternal(array, lowIndex, keyIndex - 1);
        quickSortInternal(array, keyIndex + 1, highIndex);
    }

    // 区间是 array[lowIndex, highIndex]
    // 1. 选择 array[lowIndex] 作为特殊的数
    // 2. 需要遍历整个区间(不能遗漏任何的数)和 选出来的数比较
    // 3. 保证 小于等于的在左边,大于等于的在右边(但没有顺序要求)
    private static int partition(long[] array, int lowIndex, int highIndex) {
    
    
        // 选择合适的方法
        return partitionHover(array, lowIndex, highIndex);
    }

    private static void swap(long[] array, int index1, int index2) {
    
    
        long t = array[index1];
        array[index1] = array[index2];
        array[index2] = t;
    }

    private static int partitionHover(long[] array, int lowIndex, int highIndex) {
    
    
        int leftIndex = lowIndex;
        int rightIndex = highIndex;
        // 选择的数是最左边的一个
        long key = array[lowIndex];
        // 选择了最左边,从右边先走
        // 停止条件 leftIndex == rightIndex
        // 循环的继续的条件 leftIndex < rightIndex
        while (leftIndex < rightIndex) {
    
    

            while (leftIndex < rightIndex && array[rightIndex] >= key) {
    
    
                rightIndex--;
            }
            // 说明 [rightIndex] 遇到了小的了

            while (leftIndex < rightIndex && array[leftIndex] <= key) {
    
    
                leftIndex++;
            }
            // 说明 [leftIndex] 遇到了大的了

            swap(array, leftIndex, rightIndex);
        }

        swap(array, lowIndex, leftIndex);

        return leftIndex;
    }

    //挖坑
    private static int partitionHoare(long[] array,int lowIndex,int highIndex){
    
    
        int leftIndex=lowIndex;
        int rightIndex=highIndex;
        long key=array[lowIndex];
        while(leftIndex<rightIndex){
    
    

            while(leftIndex<rightIndex&&array[highIndex]>=key){
    
    
                rightIndex--;

            }
            //右边的值
            array[leftIndex]=array[rightIndex];

            while(leftIndex<rightIndex&&array[leftIndex]<key){
    
    
                leftIndex++;
            }
            array[rightIndex]=array[leftIndex];
        }
        array[leftIndex]=key;
        return leftIndex;
    }
//前后遍历的方法
    private static int partition前后(long[] array,int lowIndex,int highIndex){
    
    
        int separateIndex=lowIndex+1;
        for(int i=lowIndex+1;i<=highIndex;i++){
    
    
            if(array[i]<array[lowIndex]){
    
    
                swap(array,i,separateIndex);
                separateIndex++;
            }
        }
        swap(array,lowIndex,separateIndex-1);
        return separateIndex-1;
    }

Guess you like

Origin blog.csdn.net/m0_46551861/article/details/109192442