Graphical analysis and detailed codes of several commonly used sorting algorithms that must be learned when entering a large factory

Diagrams and detailed codes of several commonly used sorting algorithms that must be met when entering a large factory

The sorting algorithm is the most popular algorithm we have ever come into contact with. Because of this, many sorting algorithms have been born, such as the well-known bubble sorting, selection sorting, and insertion sorting. The principles of these are very simple. After understanding The code implementation is also relatively simple, so the author will not repeat the cliché here, and students who don’t know can search related blogs and video learning.

Next, this article mainly introduces five relatively complex sorting algorithms, namely quick sorting, Hill sorting, merge sorting, radix sorting and heap sorting. Some students may ask that there are already several sorting algorithms above. Why are there so many different algorithms born? In fact, you can know this problem after serious thinking. The simplest point is that the above algorithms cannot meet some of our needs to a certain extent. This is about a section of algorithm or code. The time complexity is higher. It can be simply understood as the number of executions of valid code in a piece of code. If you want to understand the clear meaning, you can find relevant information for learning.

Back to the topic, this article mainly introduces the diagrams and code implementation of these five sorting algorithms. This is the author who spent a whole day working hard to sort it out. The author is also a novice algorithm. You can exchange, discuss and share more. I hope the boss can point out the wrong place.

a quick sort

The idea of ​​quick sorting is to complete the sorting by continuously transforming the axis point elements

What are Pivot Elements?

In ascending order, the axis point element is that all elements on the left are smaller than this element, and all elements on the right are larger than this element

Taking the following picture as an example, we first need to assume a pivot point element, then place all smaller ones on its left and larger ones on its right, and then complete the final sorting recursively

The process is as follows:

1) First of all, two pointers must be defined. At the beginning, they point to the beginning and the end respectively, which are left and right respectively.

2) Assuming that the first element is used as the pivot point element, we first scan from the right to the left, and compare the value of the right position with the assumed index value. ① If it is greater than the value of the pivot element, it will not move, and the right pointer points
to Move to the left once, repeat the above operation
②If it is smaller than the value of the pivot element, assign the value to the position corresponding to left, and move left to the right once, at this time it needs to be reversed, start scanning from left to right, repeat the above operation

3) Repeat the operation of the above 2 until the critical point, that is, left < right, exit the operation

4) Assign the value of the hypothetical axis point element to the position of the last index, and return the index

At this point, the first round of selecting the pivot element is completed, and we can know that the left side of the pivot element is smaller than the pivot element, we can select the pivot element again from the left to the pivot element, and use the pivot From the point element to the right, select the axis point element once as the boundary, and so on, we can easily sort all the elements. When recursing, we need to determine a clear boundary to ensure that the recursive function can backtrack, otherwise it will cause an infinite loop. , we can know that the limit at this time is left < right, and the function can be called until the limit is met within this limit, that is, there is only one element left, which ensures that the sorting of all elements is successful

insert image description here
insert image description here
insert image description here

code show as below:

public class QuickSort {
    
    
    public static void main(String[] args) {
    
    

        int[] arr = {
    
    6,3,5,8,1,9,7,2,0};
        int i = pivotIndex(arr, 0, arr.length);
        System.out.println(Arrays.toString(arr));
    }

    //对[begin,end) 范围内的元素进行快速排序
    public static void quickSort(int[] arr,int begin,int end){
    
    
        
        if (end - begin < 2){
    
    
            return;
        }
        //对范围内元素进行快速排序确定轴点
        int mid = pivotIndex(arr, begin, end);

        //对轴点元素左边进行快速排序
        quickSort(arr, begin, mid);
        //对轴点元素右边进行快速排序
        quickSort(arr, mid + 1, end);


    }

    /**
     * 构建范围在[begin,end)范围内元素的轴点元素
     *
     * @return  返回轴点元素的最终位置
     */
    public static int pivotIndex(int[] arr,int begin,int end){
    
    

        //备份begin元素值
        int pivot = arr[begin];

        //将end元素指向最后一个元素
        end--;

        //具体操作逻辑构建轴点元素位置

        while (begin < end){
    
    
            while(begin < end){
    
    
                //从右往左判断
                if (pivot < arr[end]){
    
    
                    end--;
                }else {
    
    
                    arr[begin++] = arr[end];
                    break;
                }
            }
            while(begin < end){
    
    
                //从左往右判断
                if (pivot > arr[begin]){
    
    
                    begin++;
                }else {
    
    
                    arr[end--] = arr[begin];
                    break;
                }
            }


        }

        //将备份的轴点元素放入最终的位置
        arr[begin] = pivot;

        return begin;
    }
}

Two Hill sort

Hill sorting is the optimization of direct insertion sorting, because considering the limit of insertion sorting, it may cause the worst time complexity

The principle is based on insertion sorting. First, the entire array is grouped by step (number of elements/2). The distance between elements in the same group is the step value, as shown in the figure below.

The elements in the same group are compared, and in ascending order, the smaller ones are placed in front and the larger ones are placed in the back

For the second time, step /= 2, and perform the above operations again until step = 1. At this time, it is the normal insertion sort, but we can see that after the above operations, the array is almost sorted

The biggest difference between Hill sorting and insertion sorting is to consider a grouping situation, and the other ideas are exactly the same as insertion sorting

insert image description here

code show as below:

The following two implementations are the same as direct insertion sort, exchange and shift

//希尔排序,就是进行分组之后的直接插入排序
public class ShellSort {
    
    

    public static int count = 0;
    public static void main(String[] args) {
    
    
        int[] arr = {
    
    6,3,5,8,1,9,7,2,0};
        shellsort1(arr);
    }

    //希尔排序之交换式
    public static void shellsort(int[] arr){
    
    
        for (int step = arr.length/2; step > 0 ; step /= 2){
    
    
            for (int i = step; i < arr.length ; i++) {
    
    
                for (int j = i-step; j >= 0 ; j -= step) {
    
    
                    if (arr[j] > arr[j+step]){
    
    
                        int temp = arr[j];
                        arr[j] = arr[j+step];
                        arr[j+step] = temp;
                    }
                }
            }
            System.out.println("希尔排序第"+ ++count +"轮:" + Arrays.toString(arr));
        }
    }

    //希尔排序之移位式
    public static void shellsort1(int[] arr){
    
    
        //将数组分组,并进行判断移位
        for (int step = arr.length/2; step > 0 ; step /= 2) {
    
    
            //这个就和简单的插入排序基本相同,只是多了一个分组的步长,需要考虑每一轮分组的情况
            for (int i = step; i < arr.length; i++) {
    
    
                int j = i;
                int temp = arr[j];
                if (arr[j] < arr[j - step]){
    
    
                    while (j - step >= 0 && temp < arr[j - step]){
    
    
                        arr[j] = arr[j - step];
                        j -= step;
                    }
                }
                arr[j] = temp;

            }
        }

        System.out.println(Arrays.toString(arr));

    }
}

triple merge sort

Merge sort is a sorting algorithm implemented by using the idea of ​​​​divide and conquer

Divide: Use recursion to break down the array into the smallest unit, that is, each element

And: in the process of backtracking the recursive function, the decomposed elements are sorted, and the sorting is completed when the backtracking is completed

Specifically as shown in the figure below:

insert image description here

The next step is to implement the sorting process and diagram in the backtracking process

The sorting in the whole backtracking process has the following steps:

1) First, a temporary array is needed to store the sorted elements

2) Three pointers left, mid, and right are needed to locate the specific position of the element and perform operations

3) Start sorting ideas

①Because they are all sorted sequentially, they are all operated from left to right, compare the values ​​at the index positions of left and tmp, and put the smaller ones in the temporary array. At this time, the index pointer moves to the right once, and the array index starts from 0

② Repeat the above operations until the critical condition is reached, that is, left <= mid && tmp <= right

③Put the remaining elements into the temporary array in turn, and the array is completely ordered at this time

④ At this time, copy the value of the temporary array to the corresponding index position of the original array in
turn (Note: it is very important, because it is a recursive backtracking process, each pointer corresponds to the beginning, end and middle position of the decomposed part, so The last sorted order needs to be used in this sorting, so the sorted temporary array should be copied to the corresponding index position of the original array, which will be reflected in the following code)

insert image description here

code show as below:

//归并排序
public class MergeSort {
    
    
    public static void main(String[] args) {
    
    
        int[] arr = {
    
    6,3,5,8,1,9,7,2,0};
        int[] temp = new int[arr.length];

        mergeSort(arr,0,arr.length-1,temp);

        System.out.println(Arrays.toString(arr));
    }


    //分解并且合并
    public static void mergeSort(int[] arr,int left,int right,int[] temp){
    
    
        if (left < right){
    
    
            int mid = (left+right)/2;

            mergeSort(arr,left,mid,temp);

            mergeSort(arr,mid+1,right,temp);

            merge(arr,left,mid,right,temp);

        }
    }



    /**
     *  合并
     * @param arr    原来的数组
     * @param left   拆分的左边序列的初始索引
     * @param mid    拆分的左边序列的结束索引
     * @param right  拆分的右边序列的结束索引
     * @param temp   用来做中转的数组
     */
    public static void merge(int[] arr ,int left,int mid,int right,int[] temp){
    
    
        int i = left;
        int j = mid + 1;
        int t = 0;

        //将序列的数组中数据按顺序放到临时数组中
        while (i <= mid && j <= right){
    
    
            if (arr[i] <= arr[j]){
    
    
                temp[t++] = arr[i++];
            }else {
    
    
                temp[t++] = arr[j++];
            }
        }

        //将剩余的数据依次放到临时数组中
        while (i <= mid){
    
    
            temp[t++] = arr[i++];
        }
        while (j <= right){
    
    
            temp[t++] = arr[j++];
        }


        //copy临时数组数据到原来数组相同的位置
        t = 0;
        int tempLeft = left;
        System.out.println("tempLeft="+tempLeft+",right="+right);
        while (tempLeft <= right){
    
    
            arr[tempLeft++] = temp[t++];
        }

    }
}

four radix sort

Using a two-dimensional array to save the sorted elements is to split a number into one-digit numbers for comparison and sorting

The size of the two-dimensional array is ten, and the corresponding index is exactly the value corresponding to each digit. You need to find the maximum value in the array first, and then determine the number of digits of the maximum value to determine how many times to compare and sort

At this time, a one-dimensional array is also needed to determine the valid data in each one-dimensional array in the two-dimensional array, so as to facilitate the retrieval of data from the two-dimensional array to the original array

The principle is to compare the size of one digit and sort it. The idea is very simple, but the code implementation still needs to think carefully

insert image description here

code show as below:

//基数排序(桶排序的优化)
public class RadixSort {
    
    
    public static void main(String[] args) {
    
    
        int[] arr = {
    
    542,3,652,784,69,123,15};
        radixSort(arr);
    }

    public static void radixSort(int[] arr){
    
    
        int max = arr[0];
        for (int i = 0; i < arr.length; i++) {
    
    
            if (arr[i] > max){
    
    
                max = arr[i];
            }
        }
        int maxLenth = String.valueOf(max).length();

        int[][] bucket = new int[10][arr.length];
        //每个桶中记录的有效元素个数
        int[] bucketEleCounts = new int[10];


        for (int k = 0,n = 1; k < maxLenth; k++,n *= 10) {
    
    
            //将原来数组元素放到桶中
            for (int i = 0; i < arr.length; i++) {
    
    
                int num = arr[i] / n % 10;
                bucket[num][bucketEleCounts[num]++] = arr[i];
            }

            int index = 0;//记录原来数组的索引值
            //将桶中数据再依次放到原来数组中
            for (int i = 0; i < bucket.length; i++) {
    
    
                if (bucketEleCounts[i] != 0){
    
    
                    for (int j = 0; j < bucketEleCounts[i]; j++) {
    
    
                        arr[index++] = bucket[i][j];
                    }
                }
                bucketEleCounts[i] = 0;
            }
            System.out.println("第"+k+"次排序后的数组:"+ Arrays.toString(arr));
        }

    }
}

Five Heap Sort

The heap sort is written at the end because it is the only algorithm among these types that needs to use the idea of ​​​​the tree data structure. It may be difficult for some friends who have not been in touch with trees to understand.

We need to know what heap sort needs to use?

Heap sorting is to convert a sequentially stored binary tree into a heap structure. Generally, a large top heap is used for ascending order, that is, the parent node of the leaf node is larger than the leaf node; a small top heap is used for descending order, that is, the parent node of the leaf node is larger than the leaf node. nodes are small

Then we have to ask what is a binary tree for sequential storage. What we need to know is that the two data structures of binary tree and array can be converted to each other.

Sequential storage of binary trees
Store binary tree structure data in the form of arrays

1) Sequential storage of binary trees usually only considers complete binary trees

Complete binary tree:

There are k-level tree structures, in which all nodes are full except for the k-th level, and try to ensure that the left subtree of the k-th level is full of nodes

2) The left child node of the nth element is 2*n+1

3) The right child node of the nth element is 2*n+2

4) The parent node of the nth element is (n-1)/2

Maybe after talking so much, some friends still don’t understand it very well. Next, I will show it in a graphical way.

insert image description here

The specific conversion process is as follows:

The specific steps for converting a binary tree to a large top heap:

①Compare the parent node of the last element with the left and right child nodes, and exchange the largest element with the parent node

② Then use the current node as the root node to judge whether the subtrees of the left and right child nodes meet the conditions of the big top heap, and then judge down in order to ensure that all the subtrees under the current node as the root node meet the conditions of the big top heap

insert image description here
insert image description here
insert image description here

After the end of the round, the root node is exchanged with the last element, and the length is reduced by one, that is, the largest element arranged is excluded, and this element will not be considered in subsequent operations

Repeat the above process of converting the big top heap again until all the elements are sorted

insert image description here

You can follow the code according to the diagram, and you should have a deeper understanding

Next is the code:

public class HeapSort {
    
    
    public static void main(String[] args) {
    
    
        int[] arr = {
    
    4,6,8,5,9,99,13,-6,-66,98,123};
        heapSort(arr);
    }

    public static void heapSort(int[] arr){
    
    

        int temp = arr[0];

        //找出最大的值放在堆的根节点
        for (int i = arr.length/2 -1; i >= 0 ; i--) {
    
    
            adjustHeap(arr,i,arr.length);
        }

        //交换根节点与最后一个节点的位置并移除最后一个节点
        for (int i = arr.length-1; i > 0  ; i--) {
    
    
            temp = arr[i];
            arr[i] = arr[0];
            arr[0] = temp;
            adjustHeap(arr,0,i);
        }

        System.out.println(Arrays.toString(arr));

    }

    /**
     * 将数组转换为大顶堆
     *
     * @param arr   要转换的数组
     * @param i     非叶子结点在数组中的索引
     * @param length  表示对多少个元素进行调整
     */
    public static void adjustHeap(int[] arr,int i,int length){
    
    

        int temp = arr[i];

        for (int j = 2 * i + 1; j < length; j = 2 * j + 1) {
    
    
            if (j+1 < length && arr[j] < arr[j+1]){
    
    
                j++;
            }
            if (arr[j] > temp){
    
    
                arr[i] = arr[j];
                i = j;
            }else {
    
    
                break;
            }
        }

        arr[i] = temp;

    }
}

To be honest, it is a bit difficult to understand. I have thought about it for a long time. It may be that my level is not enough to explain it in an easy-to-understand manner. I hope that some big guys can help point out any problems or what can be improved.

After reading it, if you feel that it is helpful to you, you can give it a thumbs up. This is the first time you have written an article with tens of thousands of words. I hope you understand if you have any questions.

Guess you like

Origin blog.csdn.net/newhandnew413/article/details/107263587