算法1.3.插入排序
一、什么是插入排序
插入排序(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∑n21+k=4n2+3n (等差数列求和)
因此平均时间复杂度为 Θ ( n 2 ) \Theta(n^2) Θ(n2)。
算法1.3.插入排序相关推荐
- [4] 算法之路 - 插入排序之Shell间隔与Sedgewick间隔
题目 插入排序法由未排序的后半部前端取出一个值.插入已排序前半部的适当位置.概念简单但速度不快. 排序要加快的基本原则之中的一个: 是让后一次的排序进行时,尽量利用前一次排序后的结果,以加快排序的速度 ...
- 我的Java开发学习之旅------Java经典排序算法之二分插入排序
一.折半插入排序(二分插入排序) 将直接插入排序中寻找A[i]的插入位置的方法改为采用折半比较,即可得到折半插入排序算法.在处理A[i]时,A[0]--A[i-1]已经按关键码值排好序.所谓折半比较, ...
- 看动画学算法之:排序-插入排序
文章目录 简介 插入排序的例子 插入排序的java程序 插入排序的时间复杂度 简介 插入排序就是将要排序的元素插入到已经排序的数组中,从而形成一个新的排好序的数组. 这个算法就叫做插入排序. 插入排序 ...
- 排序算法:直接插入排序算法实现及分析
直接插入排序算法介绍 还是先过一遍定义.直接插入排序(Straight Insertion Sort)的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的.记录数增1的有序表.来我们用通 ...
- php代码编写直接插入排序算法,PHP排序算法之直接插入排序(Straight Insertion Sort)实例分析...
本文实例讲述了PHP排序算法之直接插入排序(Straight Insertion Sort).分享给大家供大家参考,具体如下: 算法引入: 在这里我们依然使用<大话数据结构>里面的一个例子 ...
- 插入排序 php,PHP排序算法之直接插入排序(Straight Insertion Sort)实例分析
本文实例讲述了PHP排序算法之直接插入排序(Straight Insertion Sort).分享给大家供大家参考,具体如下: 算法引入: 在这里我们依然使用<大话数据结构>里面的一个例子 ...
- 插入排序java_排序算法之直接插入排序Java实现
排序算法之直接插入排序 舞蹈演示排序: 冒泡排序: http://t.cn/hrf58M 希尔排序:http://t.cn/hrosvb 选择排序:http://t.cn/hros6e 插入排序:ht ...
- 小学生图解排序算法:③直接插入排序
直接插入排序 含义:将一个记录插入到一个有序列表中的合适位置,并要求新列表依然是有序的. 算法思路 以对一个给定长度为n的无序数组a[]从小到大排列为例. 1. 假定数组的第二位a[1]至末位a[n- ...
- 排序算法(2)直接插入排序
排序算法(2)直接插入排序 原理:将数组中的所有元素依次和前面的已经排好序的元素相比较(依次) ,如果选择的元素比已排序的元素小,则交换,直到全部元素都比较过. 代码实现: void InsertS ...
- (六)Java算法:二分插入排序
目录 一.前言 二.maven依赖 三.实现 3.1.详解版 3.2.日志精简版 结语 一.前言 插入排序常见的有两种:直接插入排序 和 二分插入排序,我们上一篇算法已经讲过了直接插入排序,现在我 ...
最新文章
- Token 认证的来龙去脉
- 经过阿里,百度一面,二面后,我总结了150道iOS面试题
- 通过福禄克LinkIQ网络电缆测试仪排除 VLAN 故障
- Microsoft Visual C++ Runtime Library 错误解决办法
- 收藏 | 深度学习框架简史:TensorFlow和PyTorch双头垄断
- JavaScript:字符串相关操作
- HTML5汽车赛道飙车游戏免费源码下载
- c#如何实现叫号操作_C#银行排队叫号系统
- 服务器电脑cpu性能排行,服务器cpu性能排行,小编教你服务器cpu性能排行
- 饼状图显示以及出现问题处理
- 基于ANSYS WORKBENCH的装配体分析
- nodejs使用Moment.js操作日期时间
- 360email讲堂:中秋佳节邮件营销大放光彩
- 【自然语言处理】详说中文自动分词
- 如何搭建并成功运营手游联运平台?
- 用Python玩我的世界(1.环境搭建)
- 【总结】最全1.5万字长文解读7大方向人脸数据集v2.0版,搞计算机视觉怎能不懂人脸...
- 西门子 s7-1200和V90伺服3轴PTO
- Android 切换全屏,取消全屏
- 5.8 前端开发日报
热门文章
- 小米VR一体机游戏开发日记(第一天)
- Netty基础招式——ChannelHandler的最佳实践
- root过程重启,免root的高级重启
- SQL 分组条件深入剖析
- 智能优化算法:人工大猩猩部队优化算法-附代码
- 算法训练第五十一天 | 309.最佳买卖股票时机含冷冻期、714.买卖股票的最佳时机含手续费、股票问题总结
- leetcode1046. 最后一块石头的重量(java)
- php redis面试题,Redis面试常见问题
- C# 控制台程序的开发和打包为一个exe文件
- php里面的箭头怎么打出来,如何使用CSS制作箭头符号