一、什么是插入排序

插入排序(Insertion Sort)是一种简单直观的排序算法,它的工作原理是构建有序序列,不断将新的元素插入到已构建的有序序列中,从而实现排序。

插入排序过程就是打扑克牌时,你逐一拿扑克牌,并在手上排序的过程。

二、插入排序实现

1 基本实现思路

假设你在和朋友打牌

你先后拿到的牌的顺序为

5 , 2 , 4 , 6 , 1 , 3 {5,2,4,6,1,3} 5,2,4,6,1,3

首先你拿到5,无需排序,这就是排完序的状态:

5 5 5

随后, 你拿到2,你需要把这张牌插入之前手上的牌,也就是5,2比5小,所以放到5前面,得到:

2 , 5 2,5 2,5​

继续,你拿到4,同上述过程,4比5小,但比2大,因此插入到5前面,2的后面,得到:

2 , 4 , 5 2,4,5 2,4,5

继续,拿到6,6大于5,因此不需要移动,得到排完序的数组:

2 , 4 , 5 , 6 2,4,5,6 2,4,5,6

后续,1和3安照此步骤进行,最后得到排完序的数组:

1 , 2 , 3 , 4 , 5 , 6 1,2,3,4,5,6 1,2,3,4,5,6

2 伪代码实现
get arr[] and arr.length //我们获取一个数组 arr ,并且得到它的长度 arr.lengthfor i = 1 to arr.length-1 // 0到(i-1)代表已经排完序的数组,由于单个数肯定属于排完序的,所以i从1开始key = arr[i] // 你拿到的牌,下面循环将其与之前的牌对比,从而找到它应该在哪个位置for j = i-1 to 0if arr[j] > key// 这里由于我们采用了数组的形式,计算机中数组属于连续空间,因此插入操作并没有像描述那样简单,插入需要将后面的数每个往后移一位exchange arr[j+1] and arr[j] //交换相当于将j往后移一位elsebreak; // 由于前面的数为排完序的状态,一旦发现拿到的牌小于某一张牌,即可确定拿到牌需放的位置,循环结束endifendfor
endfor

插入排序的实现也非常简单,关注公众号 愿人人如龙 回复插入排序即可免费领取c++代码(代码非常简陋,仅供学习使用),如有错误,非常感谢你通知我。

三、算法分析

1 空间复杂度

需要额外用于交换数据的一个储存位置 Θ ( 1 ) \Theta(1) Θ(1)

2 时间复杂度

对于插入排序,主要需要通过统计对比牌的次数和交换牌的次数。

考虑最差的情况(逆序状态)

第二张牌插入第一张牌最多需要对比一次,加交换一次;

第三张牌插入,需要最多对比两次,交换两次;

第n张牌插入,需要最多对比n-1次,交换n-1次。

因此,最坏情况为 2 ( 1 + 2 + . . . + n − 1 ) = n ( n − 1 ) 2(1+2+...+n-1)=n(n-1) 2(1+2+...+n−1)=n(n−1), 时间复杂度为 Θ ( n 2 ) \Theta(n^2) Θ(n2)​

考虑最好情况(顺序状态)

每次循环只需要对比一次,发现要插入的牌大于最右边那张牌,循环结束。

一共 n-1次循环,时间复杂度为 Θ ( n ) \Theta(n) Θ(n)

平均情况

但是一般情况下,我们得到的数组不是最好情况也不是最坏情况。

首先,假设数组的排列是等可能性的,也就是说,顺序和逆序的概率都为 1 n ! \displaystyle\frac{1}{n!} n!1​,可以看到当n较大时概率非常低。​

总的来说,需要非常好的状态时算法才有 Θ ( n ) \Theta(n) Θ(n),大部分情况时间复杂度为 Θ ( n 2 ) \Theta(n^2) Θ(n2) 。

考虑一个数组,当操作第k个数时,

有 1 , 2 , 3... , k − 1 1,2,3...,k-1 1,2,3...,k−1,需要比较1到k-1次(由于交换次数与比较基本一致,不影响时间复杂度的数量级,因此不考虑),考虑排列是等可能的,所以插入每个位置为等可能的,包含自己原来的位置共有k个位置可放置,概率为 1 k \displaystyle\frac{1}{k} k1​,比较次数从右到左需要 1 , 2 , 3... , k − 1 , k − 1 1,2,3...,k-1,k-1 1,2,3...,k−1,k−1,放在第一个数字前后的比较次数均为k-1次,因此期望为 1 k ( 1 + 2 + 3... + k − 1 + k − 1 ) = ( ( 1 + k ) k 2 − 1 ) 1 k \displaystyle\frac{1}{k}(1+2+3...+k-1+k-1)=(\frac{(1+k)k}{2}-1)\frac{1}{k} k1​(1+2+3...+k−1+k−1)=(2(1+k)k​−1)k1​

将括号里-1忽略,比较次数的期望为 1 + k 2 \displaystyle\frac{1+k}{2} 21+k​

对于一个规模为n的数组,总的期望比较次数为

∑ k = 1 n 1 + k 2 = n 2 + 3 n 4 \displaystyle\sum_{k=1}^{n}\frac{1+k}{2}=\frac{n^2+3n}{4} k=1∑n​21+k​=4n2+3n​ (等差数列求和)​

因此平均时间复杂度为 Θ ( n 2 ) \Theta(n^2) Θ(n2)​。

算法1.3.插入排序相关推荐

  1. [4] 算法之路 - 插入排序之Shell间隔与Sedgewick间隔

    题目 插入排序法由未排序的后半部前端取出一个值.插入已排序前半部的适当位置.概念简单但速度不快. 排序要加快的基本原则之中的一个: 是让后一次的排序进行时,尽量利用前一次排序后的结果,以加快排序的速度 ...

  2. 我的Java开发学习之旅------Java经典排序算法之二分插入排序

    一.折半插入排序(二分插入排序) 将直接插入排序中寻找A[i]的插入位置的方法改为采用折半比较,即可得到折半插入排序算法.在处理A[i]时,A[0]--A[i-1]已经按关键码值排好序.所谓折半比较, ...

  3. 看动画学算法之:排序-插入排序

    文章目录 简介 插入排序的例子 插入排序的java程序 插入排序的时间复杂度 简介 插入排序就是将要排序的元素插入到已经排序的数组中,从而形成一个新的排好序的数组. 这个算法就叫做插入排序. 插入排序 ...

  4. 排序算法:直接插入排序算法实现及分析

    直接插入排序算法介绍 还是先过一遍定义.直接插入排序(Straight Insertion Sort)的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的.记录数增1的有序表.来我们用通 ...

  5. php代码编写直接插入排序算法,PHP排序算法之直接插入排序(Straight Insertion Sort)实例分析...

    本文实例讲述了PHP排序算法之直接插入排序(Straight Insertion Sort).分享给大家供大家参考,具体如下: 算法引入: 在这里我们依然使用<大话数据结构>里面的一个例子 ...

  6. 插入排序 php,PHP排序算法之直接插入排序(Straight Insertion Sort)实例分析

    本文实例讲述了PHP排序算法之直接插入排序(Straight Insertion Sort).分享给大家供大家参考,具体如下: 算法引入: 在这里我们依然使用<大话数据结构>里面的一个例子 ...

  7. 插入排序java_排序算法之直接插入排序Java实现

    排序算法之直接插入排序 舞蹈演示排序: 冒泡排序: http://t.cn/hrf58M 希尔排序:http://t.cn/hrosvb 选择排序:http://t.cn/hros6e 插入排序:ht ...

  8. 小学生图解排序算法:③直接插入排序

    直接插入排序 含义:将一个记录插入到一个有序列表中的合适位置,并要求新列表依然是有序的. 算法思路 以对一个给定长度为n的无序数组a[]从小到大排列为例. 1. 假定数组的第二位a[1]至末位a[n- ...

  9. 排序算法(2)直接插入排序

    排序算法(2)直接插入排序 原理:将数组中的所有元素依次和前面的已经排好序的元素相比较(依次)  ,如果选择的元素比已排序的元素小,则交换,直到全部元素都比较过. 代码实现: void InsertS ...

  10. (六)Java算法:二分插入排序

    目录 一.前言 二.maven依赖 三.实现 3.1.详解版 3.2.日志精简版 结语 一.前言   插入排序常见的有两种:直接插入排序 和 二分插入排序,我们上一篇算法已经讲过了直接插入排序,现在我 ...

最新文章

  1. Token 认证的来龙去脉
  2. 经过阿里,百度一面,二面后,我总结了150道iOS面试题
  3. 通过福禄克LinkIQ网络电缆测试仪排除 VLAN 故障
  4. Microsoft Visual C++ Runtime Library 错误解决办法
  5. 收藏 | 深度学习框架简史:TensorFlow和PyTorch双头垄断
  6. JavaScript:字符串相关操作
  7. HTML5汽车赛道飙车游戏免费源码下载
  8. c#如何实现叫号操作_C#银行排队叫号系统
  9. 服务器电脑cpu性能排行,服务器cpu性能排行,小编教你服务器cpu性能排行
  10. 饼状图显示以及出现问题处理
  11. 基于ANSYS WORKBENCH的装配体分析
  12. nodejs使用Moment.js操作日期时间
  13. 360email讲堂:中秋佳节邮件营销大放光彩
  14. 【自然语言处理】详说中文自动分词
  15. 如何搭建并成功运营手游联运平台?
  16. 用Python玩我的世界(1.环境搭建)
  17. 【总结】最全1.5万字长文解读7大方向人脸数据集v2.0版,搞计算机视觉怎能不懂人脸...
  18. 西门子 s7-1200和V90伺服3轴PTO
  19. Android 切换全屏,取消全屏
  20. 5.8 前端开发日报

热门文章

  1. 小米VR一体机游戏开发日记(第一天)
  2. Netty基础招式——ChannelHandler的最佳实践
  3. root过程重启,免root的高级重启
  4. SQL 分组条件深入剖析
  5. 智能优化算法:人工大猩猩部队优化算法-附代码
  6. 算法训练第五十一天 | 309.最佳买卖股票时机含冷冻期、714.买卖股票的最佳时机含手续费、股票问题总结
  7. leetcode1046. 最后一块石头的重量(java)
  8. php redis面试题,Redis面试常见问题
  9. C# 控制台程序的开发和打包为一个exe文件
  10. php里面的箭头怎么打出来,如何使用CSS制作箭头符号