> 如果阅读时,发现错误,或者动画不可以显示的问题可以添加我微信好友 **[tan45du_one](https://raw.githubusercontent.com/tan45du/tan45du.github.io/master/个人微信.15egrcgqd94w.jpg)** ,备注 github + 题目 + 问题 向我反馈 > > 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。 > > 另外希望手机阅读的同学可以来我的 [**公众号:袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png) 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)进入。 ### **直接插入排序(Straight Insertion Sort)** 袁记菜馆内 袁厨:好嘞,我们打烊啦,一起来玩会扑克牌吧。 小二:好啊,掌柜的,咱们玩会斗地主吧。 相信大家应该都玩过扑克牌吧,我们平常摸牌时,是不是一边摸牌,一边理牌,摸到新牌时,会将其插到合适的位置。这其实就是我们的插入排序思想。 直接插入排序:将一个记录插入到已经排好序的有序表中,从而得到一个新的有序表。通俗理解,我们首先将序列分成两个区间,有序区间和无序区间,我们每次在无序区间内取一个值,在已排序区间中找到合适的插入位置将其插入,并保证已排序区间一直有序。下面我们看一下动图吧。 注:为了更清晰表达算法思想,则采用了挖掉待排序元素的形式展示,后面也会采取此形式表达。 ![直接插入排序](https://cdn.jsdelivr.net/gh/tan45du/test1@master/20210122/直接插入排序.2marc4epuzy0.gif) **直接插入排序代码** ```java class Solution { public int[] sortArray(int[] nums) { //注意 i 的初始值为 1,也就是第二个元素开始 for (int i = 1; i < nums.length; ++i) { //待排序的值 int temp = nums[i]; //需要注意 int j; for (j = i-1; j >= 0; --j) { //找到合适位置 if (temp < nums[j]) { nums[j+1] = nums[j]; continue; } //跳出循环 break; } //插入到合适位置,这也就是我们没有在 for 循环内定义变量的原因 nums[j+1] = temp; } return nums; } } ``` **直接插入排序时间复杂度分析** 最好情况时,也就是有序的时候,我们不需要移动元素,每次只需要比较一次即可找到插入位置,那么最好情况时的时间复杂度为O(n)。 最坏情况时,即待排序表是逆序的情况,则此时需要比较2+3+....+n = (n+2)*(n-1)/2,移动次数也达到了最大值,3 +4+5+....n+1 = (n+4)*(n-1)/2,时间复杂度为O(n^2). 我们每次插入一个数据的时间复杂度为O(n),那么循环执行 n 次插入操作,平均时间复杂度为O(n^2)。 **直接插入排序空间复杂度分析** 根据动画可知,插入排序不需要额外的存储空间,所以其空间复杂度为O(1) **直接插入排序稳定性分析** 我们根据代码可知,我们只会移动比 temp 值大的元素,所以我们排序后可以保证相同元素的相对位置不变。所以直接插入排序为稳定性排序算法。 ![](https://cdn.jsdelivr.net/gh/tan45du/bedphoto2@master/20210122/微信截图_20210128084750.6911k6mnrac0.png)