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

算法-插入排序

插入排序实现

以下是插入排序的Python实现。

让我们来一步步地讲解。我会先摘出代码片段,然后给出解释。

首先,发起一个从索引1开始的循环来遍历数组。变量index保存的是当前索引。

然后在内部发起一个while循环,以检查position左侧的值是否大于temp_value。若是,则用array[position]=array[position -1]将该值右移一格,并将position减1。然后继续检查新position左侧的值是否大于temp_value……如此重复,直至遇到的值比temp_value小。

最后,将temp_value放回到数组的空隙中。

插入排序效率分析

插入排序包含4种步骤:移除、比较、平移和插入。要分析插入算法的效率,就得把每种步骤都统计一遍。

首先看看比较。每次拿temp_value跟空隙左侧的值比大小就是比较。

在数组完全逆序的最坏情况下,我们每一轮都要将temp_value左侧的所有值与temp_value比较。因为那些值全都大于temp_value,所以每一轮都要等到空隙移到最左端才能结束。

在第一轮,temp_value为索引1的值,由于temp_value左侧只有一个值,所以最多进行一次比较。到了第二轮,最多进行两次比较,以此类推。到最后一轮时,就要拿temp_value以外的所有值与其进行比较。换言之,如果数组有N个元素,则最后一轮中最多进行N -1次比较。

因而可以得出比较的总次数为:

1 + 2 + 3 + … + N -1次。

对于有5个元素的数组,最多需要:

1 + 2 + 3 + 4=10次比较。

对于有10个元素的数组,最多需要:1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9=45次比较。

(对于有20个元素的数组,最多需要190次比较,以此类推。)

由此可发现一个规律:对于有N个元素的数组,大约需要$N^{2}$/ 2次比较(102/ 2是50,202/ 2是200)。

接下来看看其他几种步骤。

我们每次将值右移一格,就是平移操作。当数组完全逆序时,有多少次比较就要多少次平移,因为每次比较的结果都会使你将值右移。

把最坏情况下的比较步数和平移步数相加。

$N^{2}$/ 2次比较+ $N^{2}$/ 2次平移=$N^{2}$

temp_value的移除跟插入在每一轮里都会各发生一次。因为总是有N -1轮,所以可以得出结论:有N -1次移除和N -1次插入。把它们都相加。$N^{2}$比较和平移的合计+ N -1次移除+ N -1次插入=$N^{2}$+ 2N -2步。

我们已经知道大O有一条重要规则——忽略常数,于是你可能会将其简化成O($N^{2}$+ N)。不过,现在来学习一下大O的另一条重要规则:大O只保留最高阶的N

换句话说,如果有个算法需要N^{4}+ N^{3}+ $N^{2}$+ N步,我们就只会关注其中的N^{4},即以O(N^{4})来表示。为什么呢?请看下表。

随着N的变大,N^{4}的增长越来越抛离其他阶。当N为1000时,N^{4}就比N^{3}大了1000倍。因此,我们只关心最高阶的N

所以在插入排序的例子中,O($N^{2}$+ N)还得进一步简化成O($N^{2}$)。你会发现,在最坏的情况里,插入排序的时间复杂度跟冒泡排序、选择排序一样,都是O($N^{2}$)。不过之前文章中指出,虽然冒泡排序和选择排序都是O($N^{2}$),但选择排序实际上是$N^{2}$/ 2步,比$N^{2}$步的冒泡排序更快。乍一看,你可能会觉得插入排序跟冒泡排序一样,因为它们都是O($N^{2}$),其实插入排序是$N^{2}$+ 2N -2步。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【React】项目的目录结构全面指南
  • Spring随笔
  • 最近火爆的GraphRAG是什么?真的那么有用吗?
  • 正则采集器之四——采集网站管理
  • 后端面试题日常练-day13 【Java基础】
  • 一些和颜色相关网站,你懂的!!!
  • random.sample() 函数原理
  • RT-DETR:DETRs Beat YOLOs on Real-time Object Detection (CVPR2024)
  • M3U8流视频数据爬虫
  • 达梦数据库的系统视图v$bufferpool
  • 学习测试12-车(略)
  • Windows下Git Bash乱码问题解决
  • C++11新增特性及右值引用
  • C#高级:枚举(Enum)从索引、值到注释的完整使用技巧
  • 养猫老手激情开麦!希喂白小罐试吃测评分享!
  • 【跃迁之路】【444天】程序员高效学习方法论探索系列(实验阶段201-2018.04.25)...
  • avalon2.2的VM生成过程
  • ERLANG 网工修炼笔记 ---- UDP
  • Java新版本的开发已正式进入轨道,版本号18.3
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • Mybatis初体验
  • Otto开发初探——微服务依赖管理新利器
  • PAT A1120
  • SAP云平台里Global Account和Sub Account的关系
  • spring + angular 实现导出excel
  • vagrant 添加本地 box 安装 laravel homestead
  • Vue.js源码(2):初探List Rendering
  • 翻译:Hystrix - How To Use
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 简单基于spring的redis配置(单机和集群模式)
  • 如何用vue打造一个移动端音乐播放器
  • 什么软件可以剪辑音乐?
  • 新版博客前端前瞻
  • 这几个编码小技巧将令你 PHP 代码更加简洁
  • [Shell 脚本] 备份网站文件至OSS服务(纯shell脚本无sdk) ...
  • 基于django的视频点播网站开发-step3-注册登录功能 ...
  • ​secrets --- 生成管理密码的安全随机数​
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • # linux 中使用 visudo 命令,怎么保存退出?
  • #define、const、typedef的差别
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • #pragma once
  • (4)事件处理——(7)简单事件(Simple events)
  • (k8s中)docker netty OOM问题记录
  • (SpringBoot)第七章:SpringBoot日志文件
  • (二) 初入MySQL 【数据库管理】
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (离散数学)逻辑连接词
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • (转)Mysql的优化设置
  • (转)关于pipe()的详细解析
  • .NET : 在VS2008中计算代码度量值
  • .NET CLR基本术语
  • .NET Core 通过 Ef Core 操作 Mysql