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

Java 实现插入排序:[通俗易懂的排序算法系列之三]

引言

大家好!欢迎继续关注我的排序算法系列。今天,我们要学习的是另一种非常基础且重要的排序算法——插入排序 (Insertion Sort)

插入排序的思路非常贴近我们日常整理扑克牌的方式,理解起来相对自然。虽然它在最坏情况下的效率不高,但在某些特定场景下,它的表现甚至优于一些更高级的排序算法。


什么是插入排序?

想象一下你在玩扑克牌,手里已经握着几张排好序的牌(比如按点数从小到大)。现在你从牌堆里摸了一张新牌,你会怎么做?

通常,你会从右手边(或左手边)已排序的牌开始,逐张比较新牌和手里的牌,找到新牌应该插入的位置,然后将该位置及其后面的牌向后挪动一点,腾出空位,把新牌插进去。

插入排序就是基于这个思想:

  1. 将整个数组分为两部分: 左边是“已排序”区间,右边是“未排序”区间。
  2. 初始状态: 已排序区间只包含数组的第一个元素 arr[0]
  3. 逐步扩展: 从未排序区间(从 arr[1] 开始)依次取出元素。
  4. 寻找位置并插入: 将取出的元素(我们称之为 currentnow)与已排序区间的元素从右向左逐一比较。
  5. 移动元素: 如果已排序区间的元素大于 current,则将该元素向右移动一位。
  6. 重复比较和移动: 继续向左比较和移动,直到找到一个小于或等于 current 的元素,或者到达已排序区间的开头。
  7. 插入:current 插入到最后移动元素的那个位置的后面(也就是空出来的位置)。
  8. 重复: 对未排序区间的所有元素重复步骤 3-7,直到所有元素都被插入到已排序区间中。

算法步骤详解 (以升序为例)

假设我们有数组 [5, 2, 4, 6, 1, 3]

  1. 初始: [5] | [2, 4, 6, 1, 3] ( | 分隔已排序和未排序)
  2. 处理 2 (now = 2):
    • 比较 25 -> 2 < 5 -> 移动 5 -> [_, 5] | [4, 6, 1, 3]
    • j 变为 -1,循环结束。
    • 插入 2j+1 (即 0) -> [2, 5] | [4, 6, 1, 3]
  3. 处理 4 (now = 4):
    • 比较 45 -> 4 < 5 -> 移动 5 -> [2, _, 5] | [6, 1, 3]
    • 比较 42 -> 4 >= 2 -> break 循环 (j 为 0)。
    • 插入 4j+1 (即 1) -> [2, 4, 5] | [6, 1, 3]
  4. 处理 6 (now = 6):
    • 比较 65 -> 6 >= 5 -> break 循环 (j 为 2)。
    • 插入 6j+1 (即 3) -> [2, 4, 5, 6] | [1, 3]
  5. 处理 1 (now = 1):
    • 比较 16 -> 1 < 6 -> 移动 6 -> [2, 4, 5, _, 6] | [3]
    • 比较 15 -> 1 < 5 -> 移动 5 -> [2, 4, _, 5, 6] | [3]
    • 比较 14 -> 1 < 4 -> 移动 4 -> [2, _, 4, 5, 6] | [3]
    • 比较 12 -> 1 < 2 -> 移动 2 -> [_, 2, 4, 5, 6] | [3]
    • j 变为 -1,循环结束。
    • 插入 1j+1 (即 0) -> [1, 2, 4, 5, 6] | [3]
  6. 处理 3 (now = 3):
    • 比较 36 -> 3 < 6 -> 移动 6 -> [1, 2, 4, 5, _, 6]
    • 比较 35 -> 3 < 5 -> 移动 5 -> [1, 2, 4, _, 5, 6]
    • 比较 34
http://www.dtcms.com/a/113533.html

相关文章:

  • 文献总结:TPAMI综述BEV感知—Delving into the devils of bird‘s-eye-view perception
  • Socket编程TCP
  • HarmonyOS:WebView 控制及 H5 原生交互实现
  • 硬件学习之器件篇-蜂鸣器
  • 第三章 react redux的学习之redux和react-redux,@reduxjs/toolkit依赖结合使用
  • use_tempaddr 笔记250405
  • setj集合
  • 1.5 基于改进蛇优化VGG13SE故障诊断方法的有效性分析
  • Python实现链接KS3,并将文件数据上传到KS3
  • 【spring Cloud Netflix】OpenFeign组件
  • 第二十九章:Python-mahotas库:图像处理的高效工具
  • 使用 pytest-xdist 进行高效并行自化测试
  • PHP的垃圾回收机制
  • 我的创作历程:从不情愿到主动分享的成长
  • 用北太天元脚本解决了关于双曲线的求离心率对应的参数、等腰三角形条件下的点坐标和向量点积条件下的参数范围
  • 如何判断栈生长的方向
  • SDL显示YUV视频
  • 快速从零部署一个DeepSeek-R1服务
  • NAS原理与技术详解:从基础概念到实践应用
  • 基础知识补充篇:关于数据不可修改
  • 功能测试和性能测试的区别有哪些?
  • 使用Geotools中的原始方法来操作PostGIS空间数据库
  • java高并发------守护线程Daemon Thread
  • Redis数据结构之ZSet
  • P3654 First Step (ファーストステップ)
  • Linux:(五种IO模型)
  • 基于SSM的高校宿舍水电管理系统
  • 0201线性回归-机器学习-人工智能
  • 开篇 - 配置Unlua+VsCode的智能提示、调试以及学习方法
  • 【LeetCode 热题100】23:合并 K 个升序链表(详细解析)(Go语言版)