数据结构与算法-排序算法3-插入排序

目录

1.插入排序:

1.介绍:

2.动态图解

3.举例

4.小结插入排序规则

5.插入排序代码

6.运行时间

代码:

运行结果:


1.插入排序:

1.介绍:

数组中n个元素,把这n个待排序元素看成一个有序序列和一个无序序列。开始时有序序列中只有一个元素,无序序列中有n-1个元素。排序过程中每次从无序序列中取出第一个元素,把它与有序序列中元素进行比较,将它插入到有序序列中的适当位置。这样有序序列中就多了一个元素,无序序列中就少了一个元素。直到无序序列中没有元素了,整个数组中元素就排好序了。

插入排序是将无序序列中元素一个个插入到有序序列中。

2.动态图解

3.举例

比如原始数组为:(17),3,25,14,20,9

第一次插入:(3,17),25,14,20,9 因为初始时17作为有序序列中的元素,3作为无序序列中的第一个元素,就把3和17比较,3更小,插入到17前面

第二次插入:(3,17,25),14,20,9 将25和(3,17)比较,在3和17之间,所以插入到中间

第三次插入:(3,14,17,25),20,9 将14和(3,17,25)比较,在3和17之间,所以插入到中间

第四次插入:(3,14,17,20,25),9 将20和(3,14,17,25)比较,在17和25之间,所以插入到中间

第五次插入:(3,9,14,17,20,25) 将9和(3,14,17,20,25)比较,在3和14之间,所以插入到中间

因为假设第一个数据是有序的,所以只需要对后面的n-1个元素进行插入。

4.小结插入排序规则

①数组元素个数为n,就一共进行n-1次插入

②每一趟插入都是先记下待插入的值,待插入数的前一个下标。在循环中找比待插入数大的数的下标,没找到就让已经比较过的有序序列中的数往后移,这个下标往前移,找到的下标就是待插入的前一个位置。所以待插入的数下标就是这个移动下标的后一个,也就是+1。

5.插入排序代码

包括推导代码和最终代码

java 复制代码
    public static void insertSort1(int[] arr) {
        //第一轮
        //定义待插入的数
        int insertVal = arr[1];//先保存
        int insertIndex = 1 - 1;//待插入数的前面一个下标
        //找到insetVal的位置
        //为了保证插入位置不越界,且待插入数还没有找到插入位置
        //就将arr[insertIndex]后移,也就是把位置让出来
        while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
            arr[insertIndex + 1] = arr[insertIndex];
            insertIndex--;
        }
        //退出循环时就已经找到插入位置,想想什么时候退出循环?
        // insertVal>=arr[insertIndex],值比找到的下标对应的值大了,那么值应该在的位置是不是在找到的下标后面。
        // insertIndex+1这个下标才是真正的待插入位置,把前面保存的待插入的数的值赋给这个下标
        arr[insertIndex + 1] = insertVal;
        System.out.println("第一轮插入:" + Arrays.toString(arr));
        //第二轮
        //定义待插入的数
        insertVal = arr[2];//先保存
        insertIndex = 2 - 1;//待插入数的前面一个下标
        //找到insetVal的位置
        //为了保证插入位置不越界,且待插入数还没有找到插入位置
        //就将arr[insertIndex]后移,也就是把位置让出来
        while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
            arr[insertIndex + 1] = arr[insertIndex];
            insertIndex--;
        }
        //退出循环时就已经找到插入位置,想想什么时候退出循环?
        // insertVal>=arr[insertIndex],值比找到的下标对应的值大了,那么值应该在的位置是不是在找到的下标后面。
        // insertIndex+1这个下标才是真正的待插入位置,把前面保存的待插入的数的值赋给这个下标
        arr[insertIndex + 1] = insertVal;
        System.out.println("第二轮插入:" + Arrays.toString(arr));
        //第三轮
        //定义待插入的数
        insertVal = arr[3];//先保存
        insertIndex = 3 - 1;//待插入数的前面一个下标
        //找到insetVal的位置
        //为了保证插入位置不越界,且待插入数还没有找到插入位置
        //就将arr[insertIndex]后移,也就是把位置让出来
        while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
            arr[insertIndex + 1] = arr[insertIndex];
            insertIndex--;
        }
        //退出循环时就已经找到插入位置,想想什么时候退出循环?
        // insertVal>=arr[insertIndex],值比找到的下标对应的值大了,那么值应该在的位置是不是在找到的下标后面。
        // insertIndex+1这个下标才是真正的待插入位置,把前面保存的待插入的数的值赋给这个下标
        arr[insertIndex + 1] = insertVal;
        System.out.println("第三轮插入:" + Arrays.toString(arr));
        //第四轮
        //定义待插入的数
        insertVal = arr[4];//先保存
        insertIndex = 4 - 1;//待插入数的前面一个下标
        //找到insetVal的位置
        //为了保证插入位置不越界,且待插入数还没有找到插入位置
        //就将arr[insertIndex]后移,也就是把位置让出来
        while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
            arr[insertIndex + 1] = arr[insertIndex];
            insertIndex--;
        }
        //退出循环时就已经找到插入位置,想想什么时候退出循环?
        // insertVal>=arr[insertIndex],值比找到的下标对应的值大了,那么值应该在的位置是不是在找到的下标后面。
        // insertIndex+1这个下标才是真正的待插入位置,把前面保存的待插入的数的值赋给这个下标
        arr[insertIndex + 1] = insertVal;
        System.out.println("第四轮插入:" + Arrays.toString(arr));
        //发现输出和推的一样,就推四轮
        /*
        第一轮插入:[3, 17, 25, 14, 20, 9]
        第二轮插入:[3, 17, 25, 14, 20, 9]
        第三轮插入:[3, 14, 17, 25, 20, 9]
        第四轮插入:[3, 14, 17, 20, 25, 9]
         */
    }

    //归纳找到规律后就用两层循环写
    public static void insertSort(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            int insertVal = arr[i];
            int insertIndex = i - 1;
            while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
                arr[insertIndex + 1] = arr[insertIndex];
                insertIndex--;
            }
            arr[insertIndex + 1] = insertVal;
            System.out.println("第" + i + "轮插入:" + Arrays.toString(arr));
        }
    }
}

运行结果:

6.运行时间

插入段记录时间的代码。排序前记一次时间,排序后记一次时间。

然后输出元素的代码就先注释掉。

代码:

java 复制代码
package com.xjj.sort;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

public class InsertSort {
    public static void main(String[] args) {
//        int[] arr = {17, 3, 25, 14, 20, 9};
//        insertSort(arr);
        int arr2[]=new int[80000];
        for(int i=0;i<80000;i++){
            arr2[i]=(int)(Math.random()*80000);
        }
        Date date1=new Date();
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date1Str=simpleDateFormat.format(date1);
        System.out.println("排序前的时间为:"+date1Str);
        insertSort(arr2);
        Date date2=new Date();
        String date2Str=simpleDateFormat.format(date2);
        System.out.println("排序后的时间为:"+date2Str);
    }

    //归纳找到规律后就用两层循环写
    public static void insertSort(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            int insertVal = arr[i];
            int insertIndex = i - 1;
            while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
                arr[insertIndex + 1] = arr[insertIndex];
                insertIndex--;
            }
            arr[insertIndex + 1] = insertVal;
//            System.out.println("第" + i + "轮插入:" + Arrays.toString(arr));
        }
    }
}

运行结果:

80000个元素,选择排序运行时间1秒。


插入排序是将无序序列中元素一个个插入到有序序列中


后面会继续写希尔排序等排序算法的内容。分类排序部分写完之后再给出一些题目练习^_^加油加油

相关推荐
华仔啊24 分钟前
Stream 代码越写越难看?JDFrame 让 Java 逻辑回归优雅
java·后端
ray_liang32 分钟前
用六边形架构与整洁架构对比是伪命题?
java·架构
AI软著研究员40 分钟前
程序员必看:软著不是“面子工程”,是代码的“法律保险”
算法
FunnySaltyFish1 小时前
什么?Compose 把 GapBuffer 换成了 LinkBuffer?
算法·kotlin·android jetpack
Ray Liang2 小时前
用六边形架构与整洁架构对比是伪命题?
java·python·c#·架构设计
颜酱2 小时前
理解二叉树最近公共祖先(LCA):从基础到变种解析
javascript·后端·算法
Java水解2 小时前
Java 中间件:Dubbo 服务降级(Mock 机制)
java·后端
SimonKing6 小时前
OpenCode AI辅助编程,不一样的编程思路,不写一行代码
java·后端·程序员
FastBean6 小时前
Jackson View Extension Spring Boot Starter
java·后端
Seven978 小时前
剑指offer-79、最⻓不含重复字符的⼦字符串
java