Eight sorting algorithms - direct insertion sorting (motion picture understanding)

Table of contents

direct insertion sort

concept

 Algorithm ideas

animation

 code show as below

Complexity Analysis

time complexity test

operation result

full code

It is not easy to create, if this blog is helpful to you, please remember to leave a message + like it.  


direct insertion sort

concept

       Insertion sort is a type of insertion sort. Insert the numbers to be sorted one by one into an ordered sequence that has been sorted until all records are inserted, and a new ordered sequence is obtained. For example, when we play poker, we use this idea.

 

 

 Algorithm ideas

        1. Starting from the first element, the element is sorted by default;

        2. Take out the next element and scan from back to front in the sorted element sequence;

        3. If the new element taken out is larger than the scanned element in the sequence (already sorted), move the scanned element to the next position.

        4. Repeat step 3 until you find the position where the sorted element is less than or equal to the new element;

        5. Insert the new element into the next position of the position (in special cases, the new element is smaller than the sorted element)

        6. Repeat steps 2~5.

animation

 

 code show as below

 public static void insertSort(int[] a){
        int i = 0;
        int j = 0;
        int tmp = 0;
        for(i = 1;i<a.length;i++){   //此层循环代表待插入的新元素 从第二个元素开始
            tmp = a[i];  //存储新元素,防止被覆盖
            j = i-1;
            while(j>=0 && a[j] > tmp){
                a[j+1] = a[j];    //已排序元素向后移动
                j--;
            }
            if(j==i-1) continue;  //说明没有进入while循环,该元素目前是最大的,不用排序
            if(j == -1 || (j>=0 && a[j]<=tmp)){ j==-1 //表示该元素目前最小
                a[j+1] = tmp;
            }
        }
    }

♣①: First of all, for single-pass insertion, because a number is to be inserted into an ordered interval, assuming that the last position of the interval is (j), then the position of the data to be inserted is (j+1), Because this data may be overwritten during the insertion process, we first save it with a variable tmp,

♣②: Then compare the data to be inserted with the last number in the ordered interval, because the default selection is ascending order, and when encountering data larger than tmp, you need to move a[end] backward, and then move forward with the subscript, Until (j<0) or a number smaller or equal to the data to be inserted is found in the middle of the comparison process, stop the comparison and jump out of this loop. With the movement of data, there will be a space after end. At this time, execute a[j + 1] = tmp to put the data to be inserted into an ordered series and keep the order in order.
 

Complexity Analysis

The closer the element set is to order, the higher the time efficiency of the direct insertion sort algorithm

Time complexity   best O(n) worst O(n^2)

Space complexity O(1) only applies for one space in tmp

Stability is stable because when there are two identical numbers, the ones added later are always behind  

time complexity test

Next, let's try to test it with a lot of data.

int[] a = new int[10_0000]; //100,000 data test

1. The orderArray function is implemented to generate a basic ordered sequence, that is, arranged from small to large.

 public static void orderArray(int[] a) {
        for (int i = 0; i < a.length; i++) {
            a[i] = i;
        }
    }

2. The notOrderArray function generates a reverse sequence, that is, arranged from largest to smallest.

 public static void notOrderArray(int[] a) {
        for (int i = 0; i < a.length; i++) {
            a[i] = a.length-i;
        }

    }

3. The randomArray function generates a random unordered array.

 public static void randomArray(int[] a) {
        Random random = new Random();
        for (int i = 0; i < a.length; i++) {
            a[i] = random.nextInt(10_0000);
        }
    }

4. The testInsertSort function tests the return value of System.currentTimeMillis() in milliseconds.

  public static void testInsertSort(int[] a){
        int[] tmpArray = Arrays.copyOf(a,a.length);
        long startTime = System.currentTimeMillis();    //注意用long接收
        insertSort(tmpArray);
        long endTime = System.currentTimeMillis();  //返回单位是毫秒
        System.out.println("直接插入排序耗时:"+(endTime-startTime));
    }

5. Main function call execution

public static void main(String[] args) {


        int[] a = new int[10_0000];
        //有序
        System.out.println("基本有序数列");
        orderArray(a);
        testInsertSort(a);

        //倒序
        System.out.println("逆序数列");
        notOrderArray(a);
        testInsertSort(a);

        //随机乱序
        System.out.println("无序数列");
        randomArray(a);
        testInsertSort(a);

    }

operation result

 

 

full code

import java.util.Random;

public class sort {

    public static void main(String[] args) {

        int[] a = new int[10_0000];
        //有序 1 2 3 4 5 ...
        System.out.println("基本有序数列");
        orderArray(a);
        testInsertSort(a);

        //逆序 9 8 7 6 5 ...
        System.out.println("逆序数列");
        notOrderArray(a);
        testInsertSort(a);

        //乱序
        System.out.println("无序数列");
        randomArray(a);
        testInsertSort(a);
    }


    //插入排序
    //时间复杂度  最好O(n)  最坏O(n^2)
    //空间复杂度 O(1)  因为只申请了 tmp 一个空间
    //稳定性  稳定 因为当有两个相同的数字时 后面加入的总在后面
    public static void insertSort(int[] a) {
        int i = 0;
        int j = 0;
        int tmp = 0;
        for(i = 1;i<a.length;i++) {
            tmp = a[i];
            j = i-1;
            while(j>=0 && a[j] > tmp) {
                a[j+1] = a[j];
                j--;
            }
            if(j==i-1) continue;
            if(j == -1 || (j>=0 && a[j]<=tmp)) {
                a[j+1] = tmp;
            }
        }
    }

    //生成有序数组  从小到大排列
    public static void orderArray(int[] a) {
        for (int i = 0; i < a.length; i++) {
            a[i] = i;
        }
    }

    //n无序 其实就是从大到小排列
    public static void notOrderArray(int[] a) {
        for (int i = 0; i < a.length; i++) {
            a[i] = a.length-i;
        }

    }

    //乱序 随机生成序列
    public static void randomArray(int[] a) {
        Random random = new Random();
        for (int i = 0; i < a.length; i++) {
            a[i] = random.nextInt(10_0000);
        }
    }

    //大量数据测试
    public static void testInsertSort(int[] a){
        int[] tmpArray = Arrays.copyOf(a,a.length);
        long startTime = System.currentTimeMillis();    //注意用long接收
        insertSort(tmpArray);
        long endTime = System.currentTimeMillis();
        System.out.println("直接插入排序耗时:"+(endTime-startTime));
    }

}

It is not easy to create, if this blog is helpful to you, please remember to leave a message + like it.  

Guess you like

Origin blog.csdn.net/m0_73381672/article/details/132020059