news 2026/5/8 17:23:00

算法基础(八)——插入排序运行时间最好最坏和平均情况

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
算法基础(八)——插入排序运行时间最好最坏和平均情况

1. 定位导航

前面已经知道,算法分析不能只看某一次运行结果,而要看输入规模变大后的增长趋势。

插入排序是理解“输入形态影响运行时间”的好例子。

对于同样长度的数组:

[1, 2, 3, 4, 5] [3, 1, 5, 2, 4] [5, 4, 3, 2, 1]

它们的长度都是 5,但插入排序的执行成本不同。

2. 概念术语

术语定义在插入排序中的体现
输入形态输入数据的原始排列状态已有序、随机、逆序
比较次数判断前面元素是否大于当前元素的次数arr[i] > key
移动次数把较大元素向后挪动的次数arr[i + 1] = arr[i]
最好情况最有利的输入数组已经有序
最坏情况最不利的输入数组完全逆序
平均情况一般随机输入下的期望表现部分元素需要移动
运行时间比较和移动共同造成的成本随输入形态变化

关键澄清:

  1. 插入排序不是对所有输入都一样慢。
  2. 已有序数组下,插入排序非常快。
  3. 完全逆序数组下,插入排序会退化到平方级。
  4. 复杂度分析要区分“输入规模”和“输入形态”。

3. 为什么插入排序的时间不固定

插入排序的核心动作是:

把当前元素插入到前面已经排好序的部分中。

如果当前元素本来就比前面元素大,就不用移动。

如果当前元素比前面很多元素都小,就要一路向前比较、移动。

所以插入排序的运行时间取决于:

当前元素需要向前移动多远。

如果数组接近有序,大部分元素几乎不用动。

如果数组完全逆序,每个元素都要移动很远。

4. 最好情况:数组已经有序

考虑输入:

[1, 2, 3, 4, 5]

插入排序从第二个元素开始处理。

每次只需要和前一个元素比较一次,就知道当前元素已经在正确位置。

例如处理2

1 <= 2

不用移动。

处理3

2 <= 3

不用移动。

所以最好情况下:

  • 每轮只做一次比较;
  • 基本没有元素移动;
  • 总比较次数大约是n - 1

因此最好情况是:

O(n) O(n)O(n)

5. 最坏情况:数组完全逆序

考虑输入:

[5, 4, 3, 2, 1]

这个输入对插入排序非常不友好。

处理4时,需要把5向后移动。

处理3时,需要把54都向后移动。

处理2时,需要把543都向后移动。

处理1时,需要把所有前面的元素都向后移动。

也就是说,每一轮都要移动大量元素。

如果数组长度是n,最坏情况下移动次数近似为:

1+2+3+⋯+(n−1) 1 + 2 + 3 + \cdots + (n - 1)1+2+3++(n1)

这个和等于:

n(n−1)2 \frac{n(n - 1)}{2}2n(n1)

所以最坏情况是:

O(n2) O(n^2)O(n2)

6. 平均情况:随机输入

随机输入时,每个元素大概不会总是在最前,也不会总是在最后。

可以粗略理解为:

平均每个元素需要向前移动前面已排序部分的一半距离。

所以平均情况下,总移动次数仍然接近平方级,只是常数比最坏情况小。

因此插入排序平均情况通常也是:

O(n2) O(n^2)O(n2)

这说明:插入排序在随机大数组上并不是理想选择。

7. 动态推演:运行轨迹对比

下面动态图对比了最好情况和最坏情况。

可以看到:

  • 最好情况中,每轮比较很少,移动次数几乎为 0;
  • 最坏情况中,每轮都会发生大量移动;
  • 同样是 5 个元素,运行成本差距已经很明显;
  • n变大时,这种差距会更大。

8. 数值推导:为什么最坏情况是平方级

最坏情况下,第几轮最多移动多少次?

处理轮次最多移动次数
第 2 个元素1
第 3 个元素2
第 4 个元素3
第 n 个元素n - 1

总移动次数就是:

1+2+3+⋯+(n−1) 1 + 2 + 3 + \cdots + (n - 1)1+2+3++(n1)

根据等差数列求和公式:

1+2+3+⋯+(n−1)=n(n−1)2 1 + 2 + 3 + \cdots + (n - 1) = \frac{n(n - 1)}{2}1+2+3++(n1)=2n(n1)

展开后:

n(n−1)2=n2−n2 \frac{n(n - 1)}{2} = \frac{n^2 - n}{2}2n(n1)=2n2n

保留最高阶项后,就是平方级:

O(n2) O(n^2)O(n2)

9. 代码实践:统计比较和移动次数

下面用代码统计三种输入下的比较次数和移动次数。

definsertion_sort_count(nums):arr=nums[:]comparisons=0moves=0forjinrange(1,len(arr)):key=arr[j]i=j-1whilei>=0:comparisons+=1ifarr[i]>key:arr[i+1]=arr[i]moves+=1i-=1else:breakarr[i+1]=keyreturnarr,comparisons,moves cases={"最好情况:已有序":[1,2,3,4,5],"平均情况:随机":[3,1,5,2,4],"最坏情况:逆序":[5,4,3,2,1],}forname,numsincases.items():sorted_arr,comparisons,moves=insertion_sort_count(nums)print(f"{name}")print(f"输入:{nums}")print(f"输出:{sorted_arr}")print(f"比较次数:{comparisons}, 移动次数:{moves}")print()

可能输出:

最好情况:已有序 输入: [1, 2, 3, 4, 5] 输出: [1, 2, 3, 4, 5] 比较次数: 4, 移动次数: 0 平均情况:随机 输入: [3, 1, 5, 2, 4] 输出: [1, 2, 3, 4, 5] 比较次数: 8, 移动次数: 4 最坏情况:逆序 输入: [5, 4, 3, 2, 1] 输出: [1, 2, 3, 4, 5] 比较次数: 10, 移动次数: 10

从结果可以明显看到:

已有序 < 随机 < 逆序

这正是最好、平均、最坏情况的差别。

10. 最好、平均、最坏的趋势对比

如果把输入规模继续放大,三种情况的趋势可以画成下面这样:

这里的重点是:

  • 最好情况接近线性增长;
  • 平均情况接近平方增长;
  • 最坏情况也是平方增长;
  • 平均情况和最坏情况差别主要体现在常数,而不是增长量级。

所以我们经常说插入排序:

最好情况 O(n) 平均情况 O(n²) 最坏情况 O(n²)

11. 常见误区

误区一:插入排序永远是 O(n²)

不准确。

插入排序最坏情况和平均情况通常是O(n²),但最好情况是O(n)

误区二:只要数据量小,就不用分析

也不对。小数据量下,复杂度影响较小,但分析仍然能帮助你理解算法行为。

误区三:逆序只是一个特殊例子,不重要

逆序输入代表最坏情况。工程中最坏情况很重要,因为系统不能只在“输入友好”时稳定。

误区四:移动次数和比较次数可以完全忽略

不能。不同实现中,移动成本可能很明显,尤其当元素对象很大时。

12. 现代延伸

插入排序虽然不是大规模通用排序的首选,但它仍然非常有用。

常见使用场景包括:

场景原因
小数组排序实现简单,常数小
数据接近有序运行时间接近线性
混合排序中的小片段复杂排序算法会在小区间切换到插入排序
在线插入场景新元素逐个到达时便于维护局部有序
教学和算法分析很适合理解循环不变式、输入形态和复杂度

很多工业级排序实现并不是单一算法,而是组合策略。

例如大数组用更适合整体排序的算法,小数组或接近有序片段再切换到插入排序,这样可以兼顾理论复杂度和实际性能。

13. 思考题

  1. 为什么插入排序在数组已经有序时是O(n)
  2. 为什么完全逆序时移动次数是1 + 2 + ... + (n-1)
  3. 平均情况下为什么仍然是平方级?
  4. 插入排序适合哪些真实工程场景?
  5. 如果数组元素是很大的对象,移动次数会带来什么额外影响?

14. 本篇小结

本篇围绕插入排序运行时间,重点讲清楚了三种情况:

  • 最好情况:数组已有序,比较少,移动少,接近O(n)
  • 最坏情况:数组完全逆序,每轮都大量移动,接近O(n²)
  • 平均情况:随机输入下通常仍然接近O(n²)
  • 输入形态会显著影响插入排序的实际运行时间;
  • 插入排序虽然不适合大规模乱序数据,但在小数组和接近有序场景中依然有价值。

算法分析不能只看一个输入样例,而要同时关注:

最好情况、最坏情况、平均情况

这才是理解算法性能的完整视角。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/8 17:22:36

【PyTorch 基础】

PyTorch 主要有以下几个基础概念&#xff1a;张量&#xff08;Tensor&#xff09;、自动求导&#xff08;Autograd&#xff09;、神经网络模块&#xff08;nn.Module&#xff09;、优化器&#xff08;optim&#xff09;等。张量&#xff08;Tensor&#xff09;张量&#xff08;…

作者头像 李华
网站建设 2026/5/8 17:21:57

谷歌SEO+外贸版GEO优化需要懂技术吗?

行业痛点分析当前&#xff0c;外贸企业在数字营销领域正面临前所未有的技术挑战&#xff0c;核心矛盾在于传统搜索引擎优化&#xff08;SEO&#xff09;策略与新兴的生成式AI搜索&#xff08;GEO&#xff09;环境之间的割裂。许多企业投入大量资源进行关键词排名&#xff0c;却…

作者头像 李华
网站建设 2026/5/8 17:21:56

基于 RMM 工具滥用的 VENOMOUS#HELPER 钓鱼攻击技术分析与防御研究

摘要 2025 年 4 月以来&#xff0c;代号VENOMOUS#HELPER的钓鱼攻击活动针对全球超 80 家机构实施定向入侵&#xff0c;核心手段为滥用 SimpleHelp 与 ScreenConnect 两类合法远程监控与管理&#xff08;RMM&#xff09;工具&#xff0c;构建冗余双通道远程控制架构&#xff0c;…

作者头像 李华
网站建设 2026/5/8 17:21:35

OpenClaw 本地 AI 操控电脑 Win11 专属优化安装全程实操教程

OpenClaw小龙虾AI v2.6.6 Win11专属部署教程&#xff5c;专业版家庭版全兼容小白实操适配系统&#xff1a;Windows 11 专业版 / 家庭版 / 正式版&#xff08;全系完美兼容&#xff09;项目简介&#xff1a;OpenClaw是GitHub星标28W的开源本地AI智能体&#xff0c;支持全自动电脑…

作者头像 李华
网站建设 2026/5/8 17:20:58

EDA创业启示:从芯片功耗痛点出发,打造系统级功耗热分析工具

1. 从芯片功耗专家到EDA创业者&#xff1a;一次深度对话的启示最近重读了一篇2012年对Docea Power公司联合创始人兼CEO Ghislain Kaiser的专访&#xff0c;感触颇深。虽然过去了十多年&#xff0c;但其中关于技术创业、市场洞察、以及电子设计自动化&#xff08;EDA&#xff09…

作者头像 李华
网站建设 2026/5/8 17:20:24

通过环境变量管理Taotoken密钥在不同部署环境的安全接入

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 通过环境变量管理Taotoken密钥在不同部署环境的安全接入 在应用开发与部署的生命周期中&#xff0c;安全地管理敏感配置信息是至关…

作者头像 李华