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

Java 插入排序:抓牌怎么排,它就怎么排

Java 插入排序:抓牌怎么排,它就怎么排

打麻将抓牌时你怎么理牌?插入排序就是那么干的

引言

插入排序(Insertion Sort)最贴近人类日常行为——手里有一副牌,新抓一张,从后往前找到合适位置插进去。

数据越有序,跑得越快。最好情况 O(n),最差 O(n²)。它不光是希尔排序的基石,更是 JDK Arrays.sort() 的核心组件之一,JDK 对小数组(< 47 个元素)默认就调用插入排序。

这篇文章,我会把插入排序讲透:

  • 用 ASCII 图演示"抓牌+理牌"的完整过程
  • 推导为什么"搬移元素"比"交换元素"更高效
  • 列出 4 个高频易错点(尤其是while条件里的>号)
  • 配套 LeetCode 147(链表插入排序)的工程实战

1. 核心思想:抓牌→理牌→再抓牌

1.1 通俗理解

想象你在打麻将,手里已经有了一堆排好序的牌:

手里:1万 3万 5万 7万(已排好序) 新抓:4万 操作:从右往左找,4万 应该插到 3万 和 5万 之间 结果:1万 3万 4万 5万 7万

1.2 ASCII 图解演示

以数组[5, 2, 4, 6, 1, 3]为例:

初始:[5, 2, 4, 6, 1, 3] 第 1 趟(i=1,key=2): 已排序部分:[5] key = 2,j = 0 arr[0] = 5 > 2,5 往后挪 → [_, 5] j = -1,退出循环 arr[0] = 2 结果:[2, 5, 4, 6, 1, 3] 第 2 趟(i=2,key=4): 已排序部分:[2, 5] key = 4,j = 1 arr[1] = 5 > 4,5 往后挪 → [2, _, 5] arr[0] = 2 < 4,停止 arr[1] = 4 结果:[2, 4, 5, 6, 1, 3] 第 3 趟(i=3,key=6): 已排序部分:[2, 4, 5] key = 6,j = 2 arr[2] = 5 < 6,停止 arr[3] = 6 结果:[2, 4, 5, 6, 1, 3] 第 4 趟(i=4,key=1): 已排序部分:[2, 4, 5, 6] key = 1,j = 3 arr[3] = 6 > 1,挪 → [2, 4, 5, _, 6] arr[2] = 5 > 1,挪 → [2, 4, _, 5, 6] arr[1] = 4 > 1,挪 → [2, _, 4, 5, 6] arr[0] = 2 > 1,挪 → [_, 2, 4, 5, 6] j = -1,退出 arr[0] = 1 结果:[1, 2, 4, 5, 6, 3] 第 5 趟(i=5,key=3): 已排序部分:[1, 2, 4, 5, 6] key = 3,j = 4 arr[4] = 6 > 3,挪 arr[3] = 5 > 3,挪 arr[2] = 4 > 3,挪 arr[1] = 2 < 3,停止 arr[2] = 3 结果:[1, 2, 3, 4, 5, 6]

1.3 三个关键观察

  1. 已排序部分逐步扩大:每趟结束后,前面 i+1 个元素一定有序
  2. 数据越有序,挪动越少:这就是为什么"基本有序"是插入排序的最佳场景
  3. 搬移 vs 交换: 一次搬移只移动一个元素(3 步赋值),一次交换要 3 步赋值(操作相同),但交换还会多做一次比较

2. 完整 Java 实现

importjava.util.Arrays;publicclassInsertionSort{/** * 插入排序(搬移元素版) * @param arr 待排序数组(原地修改) */publicstaticvoidinsertionSort(int[]arr){if(arr==null||arr.length<2){return;}intn=arr.length;// 从第 2 个元素开始(第 1 个视为已排序)for(inti=1;i<n;i++){intkey=arr[i];intj=i-1;// 把比 key 大的元素统统往后挪while(j>=0&&arr[j]>key){arr[j+1]=arr[j];j--;}// 插入 key 到正确位置arr[j+1]=key;}}
http://www.jsqmd.com/news/1053150/

相关文章:

  • HandheldCompanion:为掌上游戏电脑打造的全能控制中心
  • 流媒体下载失败频发?N_m3u8DL-RE 5分钟解决90%常见问题
  • Gemini 3.1 Pro实测:长上下文理解与结构化输出的工程落地指南
  • 智慧农业机器人路径规划 采摘机器人数据集 农业机器人田垄识别数据集 YOLO格式数据集第10754期
  • DeepSeek V4工程落地指南:稳、省、准的生产级大模型实践
  • Playwright多浏览器并发性能对比:Chromium、Firefox与WebKit实战测评
  • 嵌入式GUI开发:emWin GUIDRV_FlexColor驱动配置与优化实践
  • Ubuntu 20.04 Nginx生产级部署与安全加固指南
  • Claude Code本地化实战指南:cc-switch换模型与Skills深度解析
  • LangChain模型配置:温度、top_p与max_tokens的协同调优实战
  • 革命性浏览器自动化:Playwright MCP深度解析与实战指南
  • Grok 3实战指南:零代码AI协作者的四大核心能力与工程化落地
  • 基于图像处理的UI视觉回归测试:从像素比对到自动化流水线
  • 190.生成模型横向对比:GAN、VAE、DDPM原理差异与优缺点分析
  • FocalLens:基于大语言模型的叙事视角自动分析与可视化系统
  • Doc-V*:主动视觉推理如何革新多页文档问答
  • Layerdivider:智能图像分层工具,将单张图片转换为可编辑PSD图层
  • VibeCoding 过时了?快来试试这种开发模式吧
  • Dify 第5课:Dify 架构设计深挖
  • 3大核心优势+9大平台支持:LinkSwift网盘直链下载助手,让你彻底告别龟速下载
  • MiniCPM-o 4.5本地部署实战:4.5B轻量模型+Gradio工业落地指南
  • LangChain智能体生产级构建:从Prompt到部署的五大关键实战
  • 跨平台开源全能阅读神器-听书器!支持多设备同步!
  • Rocky Linux 8 下 Nginx 安装与生产级配置全指南
  • 2026古代采石场遗址亲身活动红黑榜,真实口碑横评不花冤枉钱 - myqiye
  • Go init函数本质:编译期初始化钩子机制解析
  • Ubuntu 16.04迁移指南:升级失败原因与安全替代方案
  • 大语言模型空间推理能力提升:TEXT2SPACE数据集与ASCII增强技术实践
  • 2026年工艺品资讯平台排行榜新鲜出炉
  • 突破2的幂次限制:基于扩展布尔函数构造灵活长度Golay互补对