数据结构与算法-排序算法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.插入排序代码

包括推导代码和最终代码

    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.运行时间

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

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

代码:

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秒。


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


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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/627081.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度学习:光流估计新范式

0.概述 在这篇文章中&#xff0c;我们将讨论两种基于深度学习的光流运动估计方法。FlowNet是第一个用于计算光流的CNN方法&#xff0c;RAFT是当前最先进的估计光流的方法。我们还将看到如何使用作者提供的经过训练的模型来使用PyTorch对新数据进行推断。 1. FlowNet FlowNet…

读人工智能时代与人类未来笔记03_演变

1. 演变 1.1. 每个社会都找到了属于自己的一套适应世界的方法 1.1.1. 适应的核心&#xff0c;是有关人类心智与现实之间关系的概念 1.1.2. 人类认识周围环境的能力 1.1.2.1. 这种能力通过知识获得&#xff0c;同时也受到知识…

CentOS 安装 SeaweedFS

1. SeaweedFS 介绍 SeaweedFS 是一个简单且高度可扩展的分布式文件系统。有两个目标&#xff1a; to store billions of files! (存储数十亿个文件&#xff01;)to serve the files fast! (快速提供文件&#xff01;) Seaweedfs的中心节点&#xff08;center master&#xff09…

电容笔记汇总

电容 一、电容理论基础 1、电容的本质 两个相互靠近的导体&#xff0c;中间夹一层不导电的绝缘介质&#xff0c;这就构成了电容器。当电容器的两个极板之间加上电压时&#xff0c;电容器就会储存电荷。 两个相互靠近的金属板中间夹一层绝缘介质组成的器件&#xff0c;当两端…

JeeSite Vue3:前端开发页面如何动态设置菜单展示模式?

推荐阅读&#xff1a; JeeSite Vue3&#xff1a;前端开发的未来之路(更新版) 随着技术的飞速发展&#xff0c;前端开发技术日新月异。在这个背景下&#xff0c;JeeSite Vue3 作为一个基于 Vue3、Vite、Ant-Design-Vue、TypeScript 和 Vue Vben Admin 的前端框架&#xff0c;引…

研发管理之认识DevOps

文章目录 一、什么是DevOps二、DevOps的背景和起源三、DevOps的特点和价值1、特点&#xff1a;2、价值&#xff1a; 四、DevOps如何帮助提高软件交付速度和质量 一、什么是DevOps DevOps&#xff08;Development和Operations的组合词&#xff09;是一组过程、方法与系统的统称…

Sketch总结

sketch禁用了lineGap https://www.sketch.com/docs/designing/text/ http://www.sketchcn.com/sketch-chinese-user-manual.html https://github.com/sketch-hq/sketch-document https://developer.sketch.com/file-format/ https://animaapp.github.io/sketch-web-viewer/ htt…

Python | Leetcode Python题解之第89题格雷编码

题目&#xff1a; 题解&#xff1a; class Solution:def grayCode(self, n: int) -> List[int]:ans [0] * (1 << n)for i in range(1 << n):ans[i] (i >> 1) ^ ireturn ans

C++基础与深度解析 | 表达式 | 操作符

文章目录 一、表达式基础1.表达式的值类别2.表达式的类型转换 二、表达式详述1.算术操作符2.逻辑与关系操作符3.位操作符4.赋值操作符5.自增与自减运算符6.其他操作符三、C17对表达式的求值顺序的限定 一、表达式基础 表达式由一到多个操作数组成&#xff0c;可以求值并 ( 通常…

2024年5月面试准备

2024年5月面试准备 资料来源Java基础泛型注解异常反射SPI机制Java集合CollectionMap 并发基础线程并发关键字并发集合Lock核心类并发集合核心类原子类核心类线程池核心类ScheduledThreadPoolExecutorForkJoinPoolFokJoinTask JUC原子类: CAS, Unsafe和原子类详解JUC 工具类 Jav…

Nginx 生产环境部署的最佳实践

你好呀&#xff0c;我是赵兴晨&#xff0c;文科程序员。 最近一段时间&#xff0c;我一直在和大家一起探讨Nginx的相关话题。期间&#xff0c;我收到了很多小伙伴的私信&#xff0c;他们好奇地问我&#xff1a;在生产环境中&#xff0c;Nginx应该如何配置&#xff1f; 他们在…

LeetCode题练习与总结:不同的二叉搜索树--96

一、题目描述 给你一个整数 n &#xff0c;求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种&#xff1f;返回满足题意的二叉搜索树的种数。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;5示例 2&#xff1a; 输入&#xff1a;n 1 输出&…

平衡三进制小数详解与进制转换

标准三进制是“逢三进一&#xff0c;退一还三”的机制&#xff0c;平衡三进制与之类似&#xff0c;但就是偏移了一下变得对称了&#xff0c;平衡三进制与标准三进制可以相互转换&#xff0c;但这样显得有点多余了&#xff0c;所以这里只讲平衡三进制与十进制的转换。 数字系统的…

_pickle.UnpicklingError: STACK_GLOBAL requires str

导致这个报错的原因是我跑yolo的时候修改数据集了&#xff0c;里面的label.cache没有删除&#xff0c;咱只要删除掉缓存就行&#xff01;&#xff01; 我这里是已经删除掉了&#xff0c;所以图片里面没有&#xff0c;一般就是在箭头所示位置有.cache文件的

Python 全栈体系【四阶】(四十三)

第五章 深度学习 九、图像分割 3. 常用模型 3.4 DeepLab 系列 3.4.1 DeepLab v1(2015) 3.4.1.1 概述 图像分割和图像分类不一样&#xff0c;要对图像每个像素进行精确分类。在使用CNN对图像进行卷积、池化过程中&#xff0c;会导致特征图尺寸大幅度下降、分辨率降低&…

windows驱动开发-PCI和中断(二)

谈到中断使用PCI总线来作为例子是最合适的&#xff0c;在Windows发展过程中&#xff0c;PCI作为最成功的底层总线&#xff0c;集成了大量的外设&#xff0c;不夸张的说&#xff0c;目前PCI几乎是唯一的总线选择&#xff0c;故大部分情况下&#xff0c;只有PCI设备驱动程序会遇到…

【回溯】1240. 铺瓷砖

本文涉及知识点 回溯 LeetCode1240. 铺瓷砖 你是一位施工队的工长&#xff0c;根据设计师的要求准备为一套设计风格独特的房子进行室内装修。 房子的客厅大小为 n x m&#xff0c;为保持极简的风格&#xff0c;需要使用尽可能少的 正方形 瓷砖来铺盖地面。 假设正方形瓷砖的…

【C++小语法】引用和内联函数(完结篇)

在使用C语言编程过程中&#xff0c;C语言的要求之严格&#xff0c;编程过程之繁琐&#xff0c;大同小异的重复性工作&#xff0c;令C之父使用C语言编程时也深受其扰&#xff0c;于是乎C兼容C小语法诞生了 一、引用 1.引用概念 在C中&#xff0c;引用&#xff08;Reference&am…

SpringCloud------Feign,Geteway

Feign 所以我们使用一门新的技术&#xff1a;声明式的http客户端Feign 第一步&#xff1a;引入依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency> …

C++ | Leetcode C++题解之第90题子集II

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<int> t;vector<vector<int>> ans;vector<vector<int>> subsetsWithDup(vector<int> &nums) {sort(nums.begin(), nums.end());int n nums.size();for (int mask …