插入排序
插入排序的原理:
在一个已经有序的数组中,在插入一个数据后,如何继续让数据继续保持有序?
这个很容易解决,先在有序的数组中找到待插入数据的位置,然后将其插入即可。
也来画个图
这就是插入排序的原理。
插入是如何借助上面的原理来实现排序。
将数据分为两个区间,已排序区间和未排序区间。初始已经排序数据仅一个数据。然后在未排序的数据中取一个元素在已经排序区间中查找插入位置,将其插入,重复这个过程。直到未排序区间为空,排序结束。
以5、3、8、2、7、1为例
插入排序包含两种操作,元素的比较,元素的移动,当插入一个数据a在已排序区间时,就拿a在已排序区间的数据依次比较,找到插入点的位置,再将插入点位置后面的数据依次
向后移动一位,最后将数据a放入到插入点。就完成了一个数据的插入排序,重复n次,就完成了一组数据的插入排序。
对于一个给定的初始序列,移动操作的次数总是固定的,就等于逆序度。
那为什么移动次数就等于逆序度?
还是刚刚的数据,来确定下移动的次数,(5、3、8、2、7、1)
对于这组数据,有序元素对是(5、8) (5、7) (3、8) (3、7) (2、7)
初始的有序度是5,逆序度是10,插入排序中,移动个数的总和也是10,(1+3+1+5)
插入排序的实现
我的插入排序的算法实现
public class InsertSort<T> implements SortInf<T> { |
老师的标准实现
public class InsertSort<T> implements SortInf<T> { |
自己与老师标准实现的区别:
不同点在于查找插入位置的方法,我的查找插入位置是从前向后查找,先找到插入点,然后将插入点的位置之后的数据,依次向后移动一位。而老师的则是直接从后向前查找,仅移动插入点后需要移动的数据,当数据不再需要移动,则说明是插入点。文字描述不够直观,还是用图下说明吧。
我的查找插入点移动数据操作
老师的查找插入点移动数据操作
通过对比发现,老师的标准插入排序,比我的更为高效,
高效的原因在于:仅遍历了需要移动的数据数据,则我的查找,无需移动的数据也进行了遍历,属于浪费。
插入排序总结
算法名称 | 最好情况时间复杂度 | 最好情况的原始数据 | 最坏情况时间复杂度 | 最坏情况的原始数据 | 平均情况时间复杂度 | 是否基于比较 | 空间复杂度 | 是否稳定排序算法 |
插入排序 | O(N) | 原始数据已经是有序,无需移动动插入 | O(
| 原始数据倒序排列 | O( | 是 | O(1) 原地排序算法 | 是 (在相等情况下,插入元素后面的位置) |