当前位置: 首页 > news >正文

【数据结构与算法】十大经典排序算法-插入排序

🌟个人博客:www.hellocode.top
🏰Java知识导航:Java-Navigate
🔥CSDN:HelloCode.
🌞知乎:HelloCode
🌴掘金:HelloCode
⚡如有问题,欢迎指正,一起学习~~


插入排序(Insertion Sort)是一种简单直观的排序算法,其基本思想是将一个记录插入到已排好序的有序序列中,直到所有记录插入完成为止。

基本思想

在这里插入图片描述

如上图所示,插入排序的基本思想就是将一个数组划分为两部分:有序部分和无序部分。通过将无序部分的元素依次插入有序部分(需要找到对应的正确位置),让每次插入的每个元素都能在正确的位置,保证有序部分始终有序,在将无序部分的元素全部插入到有序部分后,整个集合也就为有序的了。

  1. 从第二个元素开始,依次将当前元素插入到已排好序的有序序列中,直到最后一个元素。
  2. 插入当前元素时,从后往前遍历已排好序的有序序列,找到当前元素在有序序列中的位置,并将其插入到该位置。
  3. 重复执行步骤2,直到所有元素都插入完毕。

举个例子,比如我们有一组数字 [5, 3, 8, 4, 2],我们可以首先把第一个数字5视为已排序序列,然后从第二个数字3开始,与已排序序列中的元素逐一比较,找到合适的位置插入。然后针对第三个数字8,我们再重复这个过程,直至所有的数字都插入到已排序序列中。

代码实现

具体的代码就是两层for循环,外层控制未排序部分的指针,内层不断循环寻找新插入元素的正确位置,代码如下:

/*** @author HelloCode* @blog https://www.hellocode.top* @date 2023年08月09日 21:45*/
public class InsertSort {public static void main(String[] args) {int[] arr = {21, 64, 32, 11, 9, 5, 3, 41, 75, 32, 12, 98, 66};System.out.println("排序前:" + Arrays.toString(arr));insertSort(arr);System.out.println("排序后:" + Arrays.toString(arr));}public static void insertSort(int[] arr) {// 外层循环,i指向数组中未排序的元素,也可以表示已经有序元素的个数for (int i = 1; i < arr.length; i++) {// 内层for指向已经排好序的最后一个元素for (int j = i - 1; j >= 0; j--) {// 开始排序,寻找新加入的元素的正确位置,(j + 1)代表新加入的元素if (arr[j + 1] >= arr[j]) {// 代表不用交换,加入即有序,直接跳出循环break;}// 否则需要进行交换,直到找到合适位置int temp = arr[j + 1];arr[j + 1] = arr[j];arr[j] = temp;}}}
}

测试:

image-20230809221142902

优化

对于插入排序,能够优化的点我认为是在为新插入元素寻找正确位置的时候,上面的代码采用的是依次比较,类似于冒泡排序的思想。如果数据量大且情况最差的时候,效率就有些不理想了,因此可以用其他方法在此处进行优化,提升插入排序的性能

二分查找:在每次需要插入元素时,使用二分查找来找到插入的位置,而不是从头到尾扫描已排序序列。这样可以将比较次数降低为O(log n)。

具体代码这里就不列了,后面可能会有专门的二分查找文章。

总结

优点

  1. 实现简单,对于部分有序的数组效率高。
  2. 对于小规模数据或者部分有序的数据,插入排序的运行时间相对较短。

缺点

  1. 对于大规模数据或者随机数据,插入排序的时间复杂度较高,为O(n^2)。
  2. 是非稳定的排序算法,即相等的元素可能会因为排序而变得顺序颠倒。

复杂度

  • 时间复杂度:O(n^2)
  • 空间复杂度:O(1)

使用场景

  1. 小型数据集:对于小型的数据集,插入排序是一种高效且简单的排序算法
  2. 部分排序的数据集:如果一个数据集大部分是排序的,那么插入排序将是一个很好的选择。例如,考虑一个场景,一个团队在一场比赛中获得了一组分数,这些分数按照高低已经被排序,但是有一个新的分数需要插入到合适的位置。在这种情况下,插入排序可以快速找到新分数的位置并把它插入到正确的位置。
  3. 外部排序:当处理非常大的数据集时,可能需要使用外部排序。外部排序是指那些不能一次性加载到内存中的数据的排序。在这种情况下,可以使用插入排序作为子程序,从外部存储器中读取元素并将它们插入到已经排序的部分中。
  4. 与其他算法结合:插入排序也可以与其他算法结合使用。例如,当需要先对数据进行排序,然后再进行一些复杂的操作时,可以使用插入排序作为预处理步骤。

相关文章:

【数据结构与算法】十大经典排序算法-插入排序

&#x1f31f;个人博客&#xff1a;www.hellocode.top &#x1f3f0;Java知识导航&#xff1a;Java-Navigate &#x1f525;CSDN&#xff1a;HelloCode. &#x1f31e;知乎&#xff1a;HelloCode &#x1f334;掘金&#xff1a;HelloCode ⚡如有问题&#xff0c;欢迎指正&#…...

如何使用PHP Smarty进行条件判断和循环?

欢迎来到PHP Smarty的世界&#xff01;如果你想要在Smarty中执行条件判断和循环&#xff0c;那么你需要了解一些基本的语法和结构。 首先&#xff0c;让我们从条件判断开始吧&#xff01;在Smarty中&#xff0c;你可以使用{if}、{elseif}和{else}语句来进行条件判断。这些语句的…...

使用svg生成图像

使用svg生成图像 每个HTML开发人员都应该对可伸缩的向量图形有一个基本的理解。本文会通过使用svg创建一个雨伞图像来介绍一下svg的基本知识。 svg介绍 SVG 意为可缩放矢量图形&#xff08;Scalable Vector Graphics&#xff09;。是一种可以在HTML中创建图像的方式。 我们…...

DNS、ARP

目录 DNS以及它的用途 DNS的解析方式 DNS的查询方式 DNS使用TCP/UDP DNS劫持 常见的DNS劫持现象 DNS劫持与HTTP劫持的不同 处理DNS劫持 DNS缓存 DNS实现负载均衡 ARP以及他的工作原理 DNS以及它的用途 DNS是域名解析服务器&#xff0c;用来将域名解析成IP。DNS工作在…...

uniapp 微信小程序 echarts地图 点击显示类目

效果如图&#xff1a; 在tooltip内axisPointer内添加 label:{show:true} 即可显示“请求离婚”的标题...

速刷算法#Day-02

有序数组的平方 方法一&#xff1a;暴力求解 排序 暴力先求平方&#xff0c;然后NT直接用sort这个方法首先对数组中的每个元素求平方&#xff0c;然后进行排序。下面是对应的C代码&#xff1a; class Solution { public:vector<int> SortedSquare(vector<int>&…...

Java怎么手动将对象注入到springboot

在Java中&#xff0c;可以使用Spring的ApplicationContext来手动将对象注入到Spring Boot中。 1. 首先&#xff0c;确保你已经在Spring Boot应用程序中引入了Spring的依赖&#xff0c;比如 spring-boot-starter 。 2. 在你的类中注入ApplicationContext对象&#xff1a; Autowi…...

twisted 18.7.0 requires PyHamcrest>=1.9.0 解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

电脑关机程序

//关机程序 1、电脑运行起来后&#xff0c;1分钟内关机。 2、如果输入&#xff1a;我是猪。就取消关机。 #include<stdio.h> #include<string.h> int main() { char input[20] { 0 }; system("shutdown -s -t 60"); again: printf(&quo…...

构建之法 - 软工教学:每天都向前推进一点点

作者&#xff1a;福州⼤学 汪璟玢⽼师 汪老师&#xff1a;每次都向前推进一点点&#xff0c;哪怕只有一点点&#xff0c;也好过什么都不做。 ​邹老师&#xff1a;对&#xff0c;几个学期下来&#xff0c;就已经超过那些“空想”的团队很远了。坚持下去&#xff01; 汪老师&…...

基于Qlearning强化学习的路径规划算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 Q值更新规则 4.2 基于Q-learning的路径规划算法设计 4.3 Q-learning路径规划流程 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022A 3.部分核心程序 ..…...

ASL国产CS5213 转VGA信号输出音频 替代AG6200安格芯片 HDMI to VGA(带音频)方案设计原理图

CS5213功能&#xff1a;HDMI转VGA带音频输出&#xff0c;专注于设计HDMI转VGA带音频输出。可替代AG6200 AG6201。 CS5213芯片是一个HDMI&#xff08;高清多媒体接口&#xff09;到VGA桥接芯片。 它将HDMI信号转换为标准VGA信号它可以在适配器、智能电缆等设备中设计。 Capst…...

springboot启动忽略某些类

springboot启动忽略某些类 描述解决方案单拉一个提交&#xff0c;把所有的涉及kafka消费的都不注入容器通过配置ComponentScan的excludeFilters配置了不生效后续处理改之前改之后解释 总结 拆分环境 感触解决实现demo参考 描述 目前我这的开发环境和测试环境数据库是两份&#…...

HCIA VLAN配置

目录 一、VLAN&#xff08;虚拟局域网 &#xff09; 二、VLAN配置思路 三、配置命令 1、创建vlan 单个创建&#xff1a; 批量创建&#xff1a; 2、交换机上的各个接口划分到对应的vlan中 单个操作&#xff1a; 批量操作&#xff1a; 3、trunk…...

微信小程序--原生

1&#xff1a;数据绑定 1&#xff1a;数据绑定的基本原则 2&#xff1a;在data中定义页面的数据 3&#xff1a;Mustache语法 4&#xff1a;Mustache的应用场景 1&#xff1a;常见的几种场景 2&#xff1a;动态绑定内容 3&#xff1a;动态绑定属性 4&#xff1a;三元运算 4&am…...

Django快速上手

1. 安装Django Django 4.x的版本只支持MySQL8及以上的版本了。如果mysql版本比较老&#xff0c;需要使用老版本的django。此处指定django版本为3.2.20 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple django3.2.202. 创建项目 创建项目 在指定目录使用命令行创建项…...

Android, 笔记+课表的app实现

NoteSchedule: 笔记课表&#xff0c;不同于超表和课程格子等笔记类软件&#xff0c;笔记课表的核心是将课表和笔记进行深度绑定&#xff0c;点击每个课表&#xff0c;就进入到笔记view中&#xff0c;点击其中的item就可以进入到笔记详情&#xff1b; 该应用已上线&#xff0c;…...

Openlayers实战:多数据分散聚合

在飞机、轮船等地图显示的应用中,很多时候会用到数据聚合,Openlayers中提供了Cluster这个API ,他作为souce的一部分,设定distance值,如果2个点的间距小于 distance 所设置的数时,就会以聚合的方式显示。从而解决了数据淤积显示的状态,非常实用。 效果图 源代码 /* * @…...

9、Kubernetes核心技术 - Volume

目录 一、概述 二、卷的类型 三、emptyDir 四、hostPath 五、NFS 5.1、master服务器上搭建nfs服务器 5.2、各个slave节点上安装nfs客户端 5.3、创建Pod 六、PV和PVC 6.1、PV 6.1.1、PV资源清单文件示例 6.1.2、PV属性说明 6.1.3、PV的状态 6.2、PVC 6.2.1、PVC资…...

HTML <small> 标签

定义和用法 <small> 标签呈现小号字体效果。 <small> 标签和它所对应的 <big> 标签一样&#xff0c;但它是缩小字体而不是放大。如果被包围的字体已经是字体模型所支持的最小字号&#xff0c;那么 <small> 标签将不起任何作用。 与 <big> 标签…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

【深度学习新浪潮】什么是credit assignment problem?

Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...

ThreadLocal 源码

ThreadLocal 源码 此类提供线程局部变量。这些变量不同于它们的普通对应物&#xff0c;因为每个访问一个线程局部变量的线程&#xff08;通过其 get 或 set 方法&#xff09;都有自己独立初始化的变量副本。ThreadLocal 实例通常是类中的私有静态字段&#xff0c;这些类希望将…...

基于Java项目的Karate API测试

Karate 实现了可以只编写Feature 文件进行测试,但是对于熟悉Java语言的开发或是测试人员,可以通过编程方式集成 Karate 丰富的自动化和数据断言功能。 本篇快速介绍在Java Maven项目中编写和运行测试的示例。 创建Maven项目 最简单的创建项目的方式就是创建一个目录,里面…...

Unity-ECS详解

今天我们来了解Unity最先进的技术——ECS架构&#xff08;EntityComponentSystem&#xff09;。 Unity官方下有源码&#xff0c;我们下载源码后来学习。 ECS 与OOP&#xff08;Object-Oriented Programming&#xff09;对应&#xff0c;ECS是一种完全不同的编程范式与数据架构…...

【SSM】SpringMVC学习笔记7:前后端数据传输协议和异常处理

这篇学习笔记是Spring系列笔记的第7篇&#xff0c;该笔记是笔者在学习黑马程序员SSM框架教程课程期间的笔记&#xff0c;供自己和他人参考。 Spring学习笔记目录 笔记1&#xff1a;【SSM】Spring基础&#xff1a; IoC配置学习笔记-CSDN博客 对应黑马课程P1~P20的内容。 笔记2…...