algorithm-base/animation-simulation/数据结构和算法/直接插入排序.md

95 lines
4.3 KiB
Java
Raw Normal View History

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