直接插入排序是什么?
当前有一个有序数组序列。如果我们想要往里面添加一个数据,并且添加完后的数组序列依旧有序。这就要用到直接插入排序。
算法核心思想
将数组逻辑上分为两个区间:待排序区间和已排序区间。
默认数组第一个元素已经有序,归属于已排序区间。然后将待排序区间的第一个数据拿出来,和已排序区间的最后一个数相比(此处以升序为例)。
如果满足升序,则待排序区间的这个数就认为它有序了,将它划分到已排序区间,开始下一次比较。
如果不满足升序,则待排序区间数据再和已排序区间的倒数第二个数据比较,依次类推,直到找到合适的位置,再将待排序数据插入。
代码实现
public static void insertSort(int[] array){
int n = array.length;
if (n <= 1) {
return;
} else {
int value = 0; //给一会要待排序的数作为临时存放点
//确定'待排序'的数,第一个数已经有序,属于已排序空间
for (int i = 1; i < n; i++) {
//待排序空间的第一个数
value = array[i];
//已排序集合的最后一个数
int j = i - 1;
//寻找要插入的位置,从i- 1 开始找,往前遍历
for (; j >= 0; j--) {
if (array[j] > value) { //这里要用临时存放点的数据比,否则连续比较会出错
array[j + 1] = array[j]; //array[j]后移
} else { //将其位置不动,归属到已排序空间
break;
}
}
//找到要插入的位置,并将本次待排序的数插入
array[j + 1] = value;
}
}
}
算法复杂度、稳定性
时间复杂度
最好:数组序列本来就有序,当前数组所有数据已经属于已排序区间。
插入的数据刚好大于数组的最后一个元素,插入数据放在序列最后即可。因为我们从尾到头遍历,只需和数组最后一个元素比较一次。时间复杂度为O(n)。
最坏:数组是降序(假设要求升序),我们先要把原数组数据都进行搬移,每次都相当于在数组头插入数据。时间复杂度为O(n^2)。
空间复杂度
因为插⼊排序算法的运⾏并不需要额外的存储空间,所以空间复杂度是O(1)。
稳定性
代码中只有出现降序时,才产生数据搬移。当出现多个相等数据时,不会产生搬移,可以保持相等数据的原有前后顺序不变,所以是稳定的