JAVA ---- classic sorting algorithm

Table of contents

1. Insertion sort

1. Direct insertion sort 

 code demo

2. Hill sorting (reducing incremental sorting)

2. Selection sort 

1. Direct selection sort 

code: 

2. Heap sort 

the code 

3. Exchange sort 

1. Bubble sort 

the code 

2. Quick Sort 

Code (with comments): 


The animation comes from the Internet 

1. Insertion sort

1. Direct insertion sort
 

Insert the records to be sorted into a sorted sequence one by one according to the size of their key values, until all the records are inserted, and a new sequence is obtained. 

It can be clearly seen from the above figure, how to insert directly, start from the second (subscript 1), compare forward, and so on

 code demo

/**
     * 插入排序
     * @param array
     */
    public static void insertSort(int[] array){
        for (int i = 1; i < array.length; i++) {
            int tmp = array[i];
            int j = i - 1;
            for (j = i - 1; j >= 0 ; j--) {
                if(array[j] > tmp){
                    //就是让大的往后挪
                    array[j + 1] = array[j];
                }else {
                    break;
                }
            }
            array[j + 1] = tmp;
        }
    }

Direct insertion summary:
1. The closer the element set is to order, the higher the time efficiency of the direct insertion sorting algorithm
2. Time complexity: O(N^2)
3. Space complexity: O(1)
4. Stability: stable

2. Hill sorting (reducing incremental sorting)

First select an integer, divide all the records in the file to be sorted into multiple groups, and classify all the records whose distance is gap into the same group, and sort the records in each group. Then, take and repeat the above grouping and sorting work. When reaching gap=1, all records are sorted in the same group 

 

/**
     * 希尔排序
     * @param array
     */
    public static void shellSort(int[] array){
        int gap = array.length;//增量
        while(gap > 1){
            gap = gap/2;
            shell(array, gap);
        }
    }
    private static void shell(int[] array, int gap){
        for (int i = gap; i < array.length; i++) {
            int tmp = array[i];
            int j = i - gap;
            for(; j >= 0; j-=gap){
                if(array[j] > tmp){
                    array[j + gap] = array[j];
                }else {
                    break;
                }
            }
            array[j + gap] = tmp;
        }
    }

Summary of Hill sorting:
1. Hill sorting is an optimization of direct insertion sorting.
2. When gap > 1, it is pre-sorted, the purpose is to make the array closer to order. When gap == 1, the array is already close to order, so it will be very fast. In this way, the overall optimization effect can be achieved.
3. The time complexity of Hill sorting is not easy to calculate, (
O(n^1.3) ~O(n^1.5) ) Because there are many ways to value the gap, it is difficult to calculate, so it is given in many books The time complexity of Hill sort is not fixed. 

4. Unstable

2. Selection sort
 

1. Direct selection sort
 

Select the smallest (or largest) element from the data elements to be sorted each time, and store it at the beginning of the sequence until all the data elements to be sorted are exhausted.

   

code: 

/**
     * 选择排序
     * @param array
     */
    public static void selectSort(int[] array) {
        int i = 0;
        for(i = 0; i < array.length; i++){
            int minIndex = i;
            int j = i + 1;
           for(j = i + 1; j < array.length; j++){
               if(array[minIndex] > array[j]){
                    minIndex = j;
               }
           }
           int tmp = array[i];
           array[i] = array[minIndex];
           array[minIndex] = tmp;
        }
    }

Summary of direct selection sorting:
1. The efficiency of direct selection sorting is not very good. Rarely used in practice
2. Time complexity: O(N^2)
3. Space complexity: O(1)
4. Stability: unstable 

2. Heap sort 

Heapsort (Heapsort) refers to a sorting algorithm designed using a stacked tree (heap) data structure, which is a type of selection sort. It selects data through the heap. It should be noted that you need to build a large heap for ascending order, and a small heap for descending order

To put it simply, turn the array into a big root heap, then swap the first one with the last one, and then turn the changed one into a big root heap, so that the largest ones will be behind 

the code 

/**
     * 堆排序
     * 把数组变成大根堆,之后让第一个和最后一个交换,然后再把换后的变成大根堆,这样最大的就都再后面了
     * @param array
     */
    public static void heapSort(int[] array){
       int end = array.length - 1;
        for (int parent = (array.length - 1 - 1) / 2; parent >= 0; parent--) {
            //和孩子节点换
            shiftDown(parent, array.length, array);
        }
       while (end > 0){
           swap(array, 0, end);
           shiftDown(0, end, array);
           end--;
       }
    }
    private static void swap(int[] array, int begin, int end){
       int tmp = array[begin];
       array[begin] = array[end];
       array[end] = tmp;
    }
    private static void shiftDown(int parent,int usedSize,int[] array) {
        int child = (2*parent) + 1;//左孩子节点
        //不越界
        while (child < usedSize){
            //先比较一下孩子们的大小,找到当中最大的
            if(child + 1 < usedSize && array[child] < array[child + 1]){
                child = child + 1;
            }
            //然后再和parent比较大小
            if(array[child] > array[parent]){
                swap(array,child, parent);
                //比完一组,parent得往下走,动起来
                parent = child;
                child = (2*parent) + 1;
            }else {
                break;
            }
        }

    }

 Heap sorting summary:
1. Time complexity: O(nlogn)
2. Space complexity: O(1)
3. Stability: unstable 

3. Exchange sort
 

1. Bubble sort 

This should be the first kind of sorting we came into contact with. It is easy to understand, so I won’t talk about it  (I wrote it before)

the code 

/**
     * 冒泡排序
     * @param array
     */
    public static void bubbleSort(int[] array){
        for (int i = 0; i < array.length - 1; i++) {
            boolean flg = false;
            for (int j = 0; j < array.length - 1 - i; j++) {
                if(array[j] > array[j+1]){
                    int tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;
                    flg = true;
                }
            }
            if(!flg){
                break;
            }
        }
    }

Summary of bubble sorting
1. Time complexity: O(N^2)
2. Space complexity: O(1)
3. Stability: stable 

2. Quick Sort
 

Any element in the element sequence to be sorted is taken as the reference value , and the set to be sorted is divided into two subsequences according to the sort code . All elements in the left subsequence are smaller than the reference value, and all elements in the right subsequence are greater than the reference value . , and then repeat the process for the leftmost subsequence until all elements are arranged in the corresponding positions. 

Code (with comments): 

Here are two commonly used methods for finding benchmarks 

1.Hoare plate 

Look at the picture above, until the left side of the key (that is, 6) is smaller than the key, and the right side is larger than the key

/**
     * 快速排序
     * @param array
     */
    public static void quickSort(int[] array){
        quick(array, 0, array.length - 1);
    }
    private static void quick(int[] array, int start, int end){
        if(start >= end){
            return;
        }
        //防止出现都在一边的情况
        int index = midOfThree(array, start, end);//找到这三个数里(start, mid, end)第二大的下标
        swap(array, start, index);//让start处是这三个里第二大的数
        //找到基准
        int pivot = partition(array, start, end);
        quick(array, start, pivot - 1);
        quick(array, pivot + 1, end);

    }

    private static int partition(int[] array, int left, int right){
        int key = array[left];
        int i = left;
        while(left < right){
            //左边的都比key小,右边的都比key大
            //必须right先走,因为如果是left先走的话,left哪里一定是一个大于key的数,因为left遇到大于key的数才停,之后和right相遇,再换,
            //那左边的被交换数一定是一个大于key的数

            //因为右边应该都是大于key的值,所以要把小于key的数抓出来
            while (left < right && array[right] >= key){
                right--;
            }
            //同理
            while(left < right && array[left] <= key){
                left++;
            }
            swap(array, left, right);
        }
        swap(array, i, left);
        return left;
    }
    private static int midOfThree(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;
            }
        }
    }
}

2. Digging method 

 

Look at the picture above, until the end of the walk, press the pivot to the last vacant position, so that the pivot on the left is smaller than the pivot, and the pivot on the right is larger than the pivot

private static int partition(int[] array, int left, int right) {
    int i = left;
    int j = right;
    int pivot = array[left];//坑挖出来了
    while (i < j) {
        while (i < j && array[j] >= pivot) {
            j--;
        } 
        array[i] = array[j];//坑位变成[j]
        while (i < j && array[i] <= pivot) {
            i++;
        } 
        array[j] = array[i];//坑位变成[i]
    } 
    array[i] = pivot;
    return i;
}

Guess you like

Origin blog.csdn.net/iiiiiihuang/article/details/131816771