Data Structure Java Edition Sorting (2)

 

Quicksort needs to be understood in conjunction with the content of the previous section❀

content

1. Optimization of quicksort

2. Merge sort

①Principle

②Performance analysis

3. Summary of the seven rankings

4. The rest of the non-comparison-based sorting

①Counting sort

② Radix sort

③Bucket sorting


1. Optimization of quicksort

This part of the content is immediately followed by the quick-sort content mentioned at the end of the Chinese section in the previous section.

The quicksort mentioned in the previous section can be sorted by starting from the left or the right.

However, in daily life, we are likely to encounter some numbers that have been arranged regularly, then if we use the above method, it will complicate the simple problem, so the random selection and the three-number middle method mentioned below are introduced to achieve

Optimization scheme ①: Random selection (still for benchmarks)

Problem: A single branch occurs when the largest or smallest number in the array sequence is randomly selected as the benchmark. Just change the original time complexity O(N²), and the space complexity is O(N).

Optimization plan ②: Chinese method of three numbers

Detailed description: That is, using the idea of ​​halving, find the numbers at both ends and the number in the middle, respectively, and compare the numbers in the middle as the benchmark. The datum can be placed at the beginning of the array, which is equivalent to converting it to find from the left

Problem solving ideas:

① Set the subscripts at both ends to start and end respectively, and set the subscript in the middle to mid; the array is array;

②当array[start]<=array[end]时:

a.array[start]>array[mid], at this time the arrangement is: mid start end

b.array[start]<array[mid], at this time the arrangement is: start mid end

Others: start mid end

当array[start]>array[end]时:

a.array[end]>array[mid], at this time the arrangement is: mid end start

b.array[start]<array[mid], at this time the arrangement is: end start mid

Others: end mid start

The code is as follows: (Using three numbers to take a complete quick sort) {recursive version}

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

    }
    public static void quick(int []array,int left,int right){
if(left>=right){
    return ;
}//找到基准之前找到中间值的大小,使用三数取中法
        int midValIndex=findMidValIndex(array,left,right);
swap(midValIndex,left);//交换中间值的大小给left,这样left就成了基准值的位置
//找基准
        int pivot=patition(array,left,right);
//递归左边的
quick(array,left,pivot-1);
//递归右边的
quick(array,pivot+1,right);
    }
    private static int findMidValIndex(int []array,int start,int end){
int mid=start+((end-start)>>>1);//防止栈的溢出
        if(array[start]<array[end]){
            if(array[mid]<array[start]){
                return start;
            }else if(array[mid]>array[end]){
                return end;
            }else{
                return mid;
            }
        }else{
            if(array[mid]>array[start]){
                return start;
            }else if(array[mid]<array[end]){
                return end;
            }else{
                return mid;
            }
        }
    }
    public static int patition(int []array,int start,int end) {
        int tmp = array[start];
        while (start < end) {
            while (start < end && array[end] >= tmp) {
                end--;
            }//end下标遇到了小于tmp的值
            array[start] = array[end];
            while (start < end && array[start] <= tmp) {
                start++;
            }//start下标遇到了大于tmp的值
            array[end] = array[start];
        }//当start=end时
        array[start]=tmp;
        return start;
    }
Optimization ③: In the partition process, the number equal to the reference value is also selected (move the same data as the reference from both sides to the front), so that the middle part will not need to recurse again, which improves the efficiency
Optimization 4: When the range to be sorted is less than a threshold (for example, 48), use direct insertion sorting (optimization is performed when the more sorted, the more ordered the data is)
  public static void insertSort2(int[] array,int start,int end) {
        for (int i = 1; i < end; i++) {
            int tmp = array[i];
            int j = i-1;
            for (; j >= start ; j--) {
                if(array[j] > tmp) {
                    array[j+1] = array[j];
                }else {
                    //array[j+1] = tmp;  只要j回退的时候,遇到了 比tmp小的元素就结束这次的比较
                    break;
                }
            }
            //j回退到了 小于0 的地方
            array[j+1] = tmp;
        }

    }
    //快速排序
    public static void quickSort(int []array){
        quick(array,0,array.length-1);

    }
    public static void quick(int []array,int left,int right){
if(left>=right){
    return ;
}if(right-left+1<=30){
    //使用直接插入排序
            insertSort2(array,left,right);
    return;
        }
//找到基准之前找到中间值的大小,使用三数取中法
        int midValIndex=findMidValIndex(array,left,right);
swap(midValIndex,left);//交换中间值的大小给left,这样left就成了基准值的位置
//找基准
        int pivot=patition(array,left,right);
//递归左边的
quick(array,left,pivot-1);
//递归右边的
quick(array,pivot+1,right);
    }
    private static int findMidValIndex(int []array,int start,int end){
int mid=start+((end-start)>>>1);//防止栈的溢出
        if(array[start]<array[end]){
            if(array[mid]<array[start]){
                return start;
            }else if(array[mid]>array[end]){
                return end;
            }else{
                return mid;
            }
        }else{
            if(array[mid]>array[start]){
                return start;
            }else if(array[mid]<array[end]){
                return end;
            }else{
                return mid;
            }
        }
    }
    public static int patition(int []array,int start,int end) {
        int tmp = array[start];
        while (start < end) {
            while (start < end && array[end] >= tmp) {
                end--;
            }//end下标遇到了小于tmp的值
            array[start] = array[end];
            while (start < end && array[start] <= tmp) {
                start++;
            }//start下标遇到了大于tmp的值
            array[end] = array[start];
        }//当start=end时
        array[start]=tmp;
        return start;
    }

A complete quicksort using the three-digit method {non-recursive version}

Problem-solving ideas: (complete with stack)

①Find the benchmark: After dividing the benchmark, put the left and right pairs on the stack; Premise: There are two elements on the left of the benchmark pivot (pivot>left+1) and two elements on the right (pivot<right-1);

② Solve the problem with the help of the stack: enter the boundary with the benchmark as the boundary and push the stack, and push the stack on both the left and right sides of the boundary. Then until the order at both ends is 1, it cannot be pushed onto the stack. Pop the stack until the stack is empty. (Note that the subscript is pushed onto the stack)

code show as below:

    public static void quickSort1(int []array){
        Stack<Integer> stack=new Stack<>();
        int left=0;
        int right=array.length-1;
        int pivot=patition(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=patition(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);
    }
}
    }

2. Merge sort

①Principle

Merge sort ( MERGE-SORT ) is an efficient sorting algorithm based on the merge operation, which is a very typical application of the divide and conquer method . Merge the ordered subsequences to obtain a completely ordered sequence; that is, first make each subsequence ordered, and then make the subsequence segments ordered. If two sorted lists are merged into one sorted list, it is called two-way merge.
Introduced: The problem of merging two sorted arrays into one array.

 code show as below:

 //两个有序表的归并
    public static  int [] mergeArray(int[]array1,int[]array2){
        int s1=0;
        int e1=array1.length-1;
        int s2=0;
        int e2=array2.length-1;
        int index=0;
        int []tmp=new int[array1.length+array2.length];
        while (s1 <= e1 && s2 <= e2) {
            if(array1[s1] <= array2[s2]) {
                tmp[index] = array1[s1];
                index++;
                s1++;
            }else {
                tmp[index] = array2[s2];
                index++;
                s2++;
            }
        }
//此时表示s2数组已经走完,把剩下的s1数组中的数依次放入合并的数组中即可
        while (s1 <= e1) {
            tmp[index++] = array1[s1++];
            //此处也可以像上面那样写成index++;s1++;
        }
//此时表示s1数组已经走完,把剩下的s2数组中的数依次放入合并的数组中即可
        while (s2 <= e2) {
            tmp[index++] = array2[s2++];
        }
        return tmp;
    }
Merge sort: (recursive version)
Problem solving ideas:
Using the idea of ​​binary tree recursion to solve the problem
①Use half search to find the middle mid value, so as to branch the root root, and perform recursive operation
② Loop the above operations until there is only one element left in the single branch, merge the two single branch elements together in order until the position corresponding to the root is reached

code show as below:

//归并排序
 public static void mergeSort1(int[] array) {
        mergeSortInternal(array,0,array.length-1);
    }

    private static void mergeSortInternal(int[] array,int low,int high) {
        if(low>=high) {
            return;
        }
        //为了避免栈的溢出的写法
        int mid = low + ((high-low) >>> 1);
        //左边递归
        mergeSortInternal(array,low,mid);
        //右边递归
        mergeSortInternal(array,mid+1,high);
        //合并
        merge(array,low,mid,high);
    }
//上面开始合并数组奠定了基础
    private static void merge(int[] array,int low,int mid,int high) {
        int[] tmp = new int[high-low+1];
        int k = 0;
        int s1 = low;
        int e1 = mid;
        int s2 = mid+1;
        int e2 =  high;
        while (s1 <= e1 && s2 <= e2) {
            if(array[s1] <= array[s2]) {
                tmp[k++] = array[s1++];
            }else {
                tmp[k++] = array[s2++];
            }
        }

        while (s1 <= e1) {
            tmp[k++] = array[s1++];
        }

        while (s2 <= e2) {
            tmp[k++] = array[s2++];
        }
        //复制tmp数组的元素 放入原来的数组array中
        for (int i = 0; i < k; i++) {
            array[i+low] = tmp[i];
        }
    }

 
Merge sort: (non-recursive version)
Problem solving ideas:
After dismantling the array like a tree, it returns to its original appearance, from 1 single data to 2 ordered data, to 4 ordered data, until it becomes the same as the original to be sorted. Columns are equal in length
code show as below:
  public static void mergeSort(int[] array) {
        int nums = 1;//单个数据的时候
        while (nums < array.length) {
            //数组每次都要进行遍历,确定要归并的区间
            for (int i = 0; i < array.length; i += nums*2) {
                int left = i;
                int mid = left+nums-1;
                //防止mid的越界
                if(mid >= array.length) {
                    mid = array.length-1;
                }
                int right = mid+nums;
                //防止right的越界
                if(right >= array.length) {
                    right = array.length-1;
                }
                //小标确定之后,进行合并
                merge(array,left,mid,right);
            }
            nums *= 2;
        }
    }

②Performance analysis

time complexity O (N * logN)
space complexity O(N)
stability Stablize

3. Summary of the seven rankings

 

4. The rest of the non-comparison-based sorting (everyone is based on the level of understanding)

①Counting sort

Counting Sort - Knowing (zhihu.com) icon-default.png?t=M1L8https://zhuanlan.zhihu.com/p/26595385?group_id=842495057868226560

② Radix sort

1.10 Radix Sort | Rookie Tutorial (runoob.com) icon-default.png?t=M1L8https://www.runoob.com/w3cnote/radix-sort.html

③Bucket sorting

Bucket sorting (the fastest and easiest sorting) - Zhihu (zhihu.com) icon-default.png?t=M1L8https://zhuanlan.zhihu.com/p/33905160 Thanks for watching~

Guess you like

Origin blog.csdn.net/weixin_58850105/article/details/123171535