直接插入排序算法

直接插入排序是一种简单直观的排序算法,它的工作原理与人们打扑克牌时整理手牌的过程非常相似。当你摸到一张新的牌时,你会将它与你手中已经排序好的牌进行比较,找到合适的位置后插入,以保持整个手牌的顺序。这种排序算法的基本思想就是,通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

一、算法原理

直接插入排序算法主要分为以下几个步骤:

  1. 初始化:将序列的第一个元素视为一个已排序的序列,剩下的元素作为未排序的序列。
  2. 逐个处理:从未排序的序列中取出一个元素,在已排序的序列中从后向前扫描。
  3. 寻找位置:在已排序的序列中找到该元素应该插入的位置。这一步通过比较来实现,如果已排序的元素大于新元素,则将该元素向后移动一位,为新元素腾出空间。
  4. 插入元素:将新元素插入到已排序序列中的正确位置。
  5. 重复步骤:重复步骤2至4,直到未排序的序列为空。
二、算法流程

以数组 [4, 2, 5, 1, 3] 为例,详细说明直接插入排序的过程:

  1. 初始状态
    • 已排序序列:[4]
    • 未排序序列:[2, 5, 1, 3]
  2. 第一轮
    • 取出未排序序列的第一个元素 2,与已排序序列 [4] 中的元素进行比较。
    • 发现 4 大于 2,因此将 4 向后移动一位,腾出位置给 2
    • 插入 2 到已排序序列中,得到新的已排序序列 [2, 4],未排序序列变为 [5, 1, 3]
  3. 第二轮
    • 取出未排序序列的第一个元素 5,与已排序序列 [2, 4] 中的元素进行比较。
    • 5 大于 4 和 2,因此直接插入到已排序序列的末尾。
    • 得到新的已排序序列 [2, 4, 5],未排序序列变为 [1, 3]
  4. 第三轮
    • 取出未排序序列的第一个元素 1,与已排序序列 [2, 4, 5] 中的元素进行比较。
    • 1 小于 2,因此将 2 及其之后的元素都向后移动一位。
    • 插入 1 到已排序序列中,得到新的已排序序列 [1, 2, 4, 5],未排序序列变为 [3]
  5. 第四轮
    • 取出未排序序列的最后一个元素 3,与已排序序列 [1, 2, 4, 5] 中的元素进行比较。
    • 3 小于 45,但大于 2,因此将 4 和 5 向后移动一位。
    • 插入 3 到已排序序列中,得到最终的已排序序列 [1, 2, 3, 4, 5]
三、代码实现

下面是直接插入排序的Java代码实现:

public class InsertionSort {  public static void insertionSort(int[] array) {  // 遍历未排序的序列  for (int i = 1; i < array.length; i++) {  // 保存当前要插入的元素  int key = array[i];  // 已排序序列的最后一个元素的索引  int j = i - 1;  // 将比key大的元素向后移动一位  while (j >= 0 && array[j] > key) {  array[j + 1] = array[j];  j--;  }  // 插入key到正确的位置  array[j + 1] = key;  }  }  public static void main(String[] args) {  int[] array = {4, 2, 5, 1, 3};  insertionSort(array);  for (int value : array) {  System.out.print(value + " ");  }  }  
}


四、性能分析

1. 时间复杂度
  • 最好情况:当输入数组已经是排序好的情况下,每次循环只需比较一次就能确定位置,此时的时间复杂度为O(n)。
  • 平均情况最坏情况:在大部分情况下,特别是输入数组随机时,每个元素都可能需要比较并移动多次。平均和最坏情况下,每个元素都可能需要与其前面的所有元素进行比较,因此时间复杂度为O(n^2)。
2. 空间复杂度

直接插入排序算法是一个原地排序算法,它只需要使用常量的额外空间来存储临时变量,因此空间复杂度为O(1)。

3. 稳定性

直接插入排序是稳定的排序算法。在排序过程中,相等元素的相对位置不会发生改变。这是因为在比较过程中,一旦找到一个大于或等于待插入元素的元素,就停止比较并插入,不会影响到相同元素的原始顺序。

五、应用场景

尽管直接插入排序在最坏情况下的时间复杂度较高,但它在实际应用中仍有一定的优势:

  • 小数据集:对于小规模的数据集,直接插入排序的效率是相当高的,因为其实现简单且不需要额外的存储空间。
  • 几乎排序的数据:如果数据已经基本有序,那么直接插入排序的性能会非常好,因为此时元素的移动次数会大大减少。
  • 链表排序:对于链表结构的数据,直接插入排序尤其高效,因为链表的插入操作非常迅速,且不需要额外的空间来存储数据。
六、优化与改进

尽管直接插入排序本身已经很高效且简单,但在某些情况下,通过一些优化手段可以进一步提高其性能:

  • 二分插入排序:在查找插入位置时,可以使用二分查找算法来减少比较次数,特别是对于大数据集或接近有序的数据集,这种优化效果显著。
  • 块排序(TimSort):Java的Arrays.sort()方法在JDK 7之后采用了TimSort算法,该算法结合了归并排序和直接插入排序的思想,在保持稳定性的同时,能够利用直接插入排序在数据量小时的高效性。

总之,直接插入排序是一种简单直观的排序算法,尽管其时间复杂度在最坏情况下较高,但在特定场景下(如小数据集、几乎排序的数据或链表排序)仍有广泛的应用价值。通过优化和改进,还可以进一步提高其性能。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

18938 汉诺塔问题

### 思路 1. **递归解决问题**&#xff1a;使用递归方法解决汉诺塔问题。 2. **递归基准**&#xff1a;当只有一个盘子时&#xff0c;直接从源杆移动到目标杆。 3. **递归步骤**&#xff1a; - 将n-1个盘子从源杆移动到辅助杆。 - 将第n个盘子从源杆移动到目标杆。 - …

JavaScript二进制浮点数和四舍五入错误

二进制浮点数和四舍五入错误 实数有无数个&#xff0c;但JS通过浮点数的形式&#xff0c;只能表示有限个数&#xff0c;JS表现的常常是真实值的近似表示。 二进制无法表示类似于0.1这样的十进制数字&#xff0c;只能机器近似于0.1&#xff0c;看如下代码&#xff1a; <!D…

Python 中的方法解析顺序(MRO)

在 Python 中&#xff0c;MRO&#xff08;Method Resolution Order&#xff0c;方法解析顺序&#xff09;是指类继承体系中&#xff0c;Python 如何确定在调用方法时的解析顺序。MRO 决定了在多继承环境下&#xff0c;Python 如何寻找方法或属性&#xff0c;即它会根据一定规则…

二,MyBatis -Plus 关于映射 Java Bean 对象的注意事项和细节(详细说明)

二&#xff0c;MyBatis -Plus 关于映射 Java Bean 对象的注意事项和细节(详细说明) 文章目录 二&#xff0c;MyBatis -Plus 关于映射 Java Bean 对象的注意事项和细节(详细说明)1. 映射2. 表的映射3. 字段映射4. 字段失效5. 视图属性6. 总结&#xff1a;7. 最后&#xff1a; 1.…

【数据优化】基于GEE填补遥感缺失数据

GEE填补遥感数据缺失 1.写在前面2.填充代码2.1 年内中值数据填充MODIS NPP空值2.2 年内中值数据填充Landsat8 NDVI空值 1.写在前面 在遥感影像分析中&#xff0c;我们经常会遇到由于云层遮挡、传感器故障等多重因素导致的图像数据缺失问题。为了解决这一挑战&#xff0c;常用的…

Selenium with Python学习笔记整理(网课+网站持续更新)

本篇是根据学习网站和网课结合自己做的学习笔记&#xff0c;后续会一边学习一边补齐和整理笔记 官方学习网站在这获取&#xff1a; https://selenium-python.readthedocs.io/getting-started.html#simple-usage WEB UI自动化环境配置 (推荐靠谱的博客文章来进行环境配置,具…

MySQL高阶之存储过程

什么是存储过程? 存储过程可称为过程化SQL语言&#xff0c;是在普通SQL语句的基础上增加了编程语言的特点&#xff0c;把数据操作语句(DML)和查询语句(DQL)组织在过程化代码中&#xff0c;通过逻辑判断、循环等操作实现复杂计算的程序语言。 换句话说&#xff0c;存储过程其实…

Acwing BFS

一般通过队列实现&#xff0c;当边的权值相同时具有最短性&#xff0c;可以求最少操作步数。相比DFS无需回溯&#xff0c;而是逐层搜索。 Acwing 844 走迷宫 输入样例&#xff1a; 5 5 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 输出样例&#xff1a; 8 思路分析&am…

Spring Boot蜗牛兼职网:全栈开发

第4章 系统设计 4.1 系统体系结构 蜗牛兼职网的结构图4-1所示&#xff1a; 图4-1 系统结构 登录系统结构图&#xff0c;如图4-2所示&#xff1a; 图4-2 登录结构图 蜗牛兼职网结构图&#xff0c;如图4-3所示。 图4-3 蜗牛兼职网结构图 4.2开发流程设计 系统流程的分析是通…

[今日Arxiv] 思维迭代:利用内心对话进行自主大型语言模型推理

思维迭代&#xff1a;利用内心对话进行自主大型语言模型推理 Iteration of Thought: Leveraging Inner Dialogue for Autonomous Large Language Model Reasoning URL&#xff1a;https://arxiv.org/abs/2409.12618 注&#xff1a;翻译可能存在误差&#xff0c;详细内容建议…

Java -2

常用API System 可以获取当前时间&#xff0c;以此计算运行代码的时间也可以控制代码的结束 //获取当前时间点-毫秒 1970 1-1 8:00 long num System.currentTimeMillis(); System.out.println(num);//系统退出运行 System.exit(0); Runtime 获取操作系统的线程大小 能从操…

YOLOv8改进 | 主干网络 | 将backbone替换为Swin-Transformer结构【论文必备】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效…

Tansformer代码实现

目录 1.Tansformer架构图 2.代码实现 2.1创建类&#xff1a;实现基于位置的前馈网络 2.2创建 残差&LN层标准归一化的类 2.3编码器block 2.4创建编码器 2.5创建解码器 2.6transformer解码器部分 3.知识点个人理解 1.Tansformer架构图 2.代码实现 2.1创建类&…

连续数组问题

目录 一题目&#xff1a; 二思路&#xff1a; 三代码&#xff1a; 一题目&#xff1a; leetcode链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 二思路&#xff1a; 思路&#xff1a;前缀和&#xff08;第二种&#xff09;化0为-1hash&#xff1a; 这样可以把…

【大模型实战篇】一种关于大模型高质量数据的处理方法-无标注数据类别快速识别及重复数据检测(加权向量-卷积神经网络-聚类算法结合)

1. 背景介绍 大模型的能力很大程度上依赖于高质量的数据&#xff0c;在之前的一篇文章《高质量数据过滤及一种BoostedBaggingFilter处理方法的介绍》中&#xff0c;我们介绍了大模型的数据处理链路&#xff0c;本文继续关注在高质量数据的模块。 本文所要介绍的处理方法&…

vscode 配置django

创建运行环境 使用pip安装Django&#xff1a;pip install django。 创建一个新的Django项目&#xff1a;django-admin startproject myproject。 打开VSCode&#xff0c;并在项目文件夹中打开终端。 在VSCode中安装Python扩展&#xff08;如果尚未安装&#xff09;。 在项…

滑动窗口经典题目

目录 滑动窗口 什么是滑动窗口&#xff1f; 什么时候用滑动窗口&#xff1f; 怎么用滑动窗口&#xff1f; 209. 长度最小的子数组&#xff08;滑动窗口的引入&#xff09; 3. 无重复字符的最长子串 1004. 最大连续1的个数 III 1658. 将 x 减到 0 的最小操作数 904. 水…

Fyne ( go跨平台GUI )中文文档-容器和布局 (四)

本文档注意参考官网(developer.fyne.io/) 编写, 只保留基本用法 go代码展示为Go 1.16 及更高版本, ide为goland2021.2 这是一个系列文章&#xff1a; Fyne ( go跨平台GUI )中文文档-入门(一)-CSDN博客 Fyne ( go跨平台GUI )中文文档-Fyne总览(二)-CSDN博客 Fyne ( go跨平台GUI…

【重学 MySQL】三十七、聚合函数

【重学 MySQL】三十七、聚合函数 基本概念5大常用的聚合函数COUNT()SUM()AVG()MAX()MIN() 使用场景注意事项示例查询 聚合函数&#xff08;Aggregate Functions&#xff09;在数据库查询中扮演着至关重要的角色&#xff0c;特别是在处理大量数据时。它们能够对一组值执行计算&a…

37. Vector3与模型位置、缩放属性

本文章给通过组对象Group (opens new window)给大家讲解一下threejs层级模型或树结构的概念。 Group层级模型(树结构)案例 下面代码创建了两个网格模型mesh1、mesh2&#xff0c;通过THREE.Group类创建一个组对象group,然后通过add方法把网格模型mesh1、mesh2作为设置为组对象g…