插入排序原理
插入排序,就是将新元素插入到已经有序的集合的恰当位置,使新集合长度+1且仍保持有序。集合开始只有一个元素,天然有序,将其他元素也依次插入,插入完成即排序完成。
排序演示1
原数组:[4,4,8,-5,-4,-7,-4,7,3],用插入排序对数组进行排序。
排序演示2
原数组:[4,4,8,-5,-4,-7,-4,7,3],用插入排序对数组进行排序。
代码实现
public static void insertSort(int[] arr){
//arr[0]天然有序,每轮插入一个元素
for(int i=1;i<arr.length;i++){
//System.out.print("第"+i+"轮,当前已排好的元素:");
//AlgorithmComparatorUtil.printIntArr(Arrays.copyOfRange(arr,0,i));
//System.out.println("要将第"+i+"索引位置元素‘"+arr[i]+"’插入到前面的集合中");
//System.out.println();
for(int j=i;j>0;j--){
//当前元素大于等于前面的元素,说明已经插入到了合适的位置,跳出循环
if(arr[j]>=arr[j-1]) break;
//没有跳出则跟前面一个元素交换位置,直到处于合适的位置
swap(arr,j-1,j);
}
}
}
public static void swap(int[] arr,int index1,int index2){
int tmp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = tmp;
}
复杂度分析
时间复杂度
对于长度为n的集合,排序过程中,每次插入一个元素,因此需要插入n-1次。每次插入都要把元素插入合适的位置,这其实是依次跟前一个元素交换位置的过程。这个过程需要的遍历次数不确定,由数据决定。因此可以衍生出最好情况和最差情况。
最好情况:[1,2,5,7,8],数组已然有序,这时候每次插入元素,都直接把他放在元素的最后面。故时间复杂度为:O(n)。
最差情况:[8,7,5,2,1],数组逆序,因此每次插入元素,都需要从最后面依次向前交换。故时间复杂度为:n * (1 + 2 + 3 + … + n) ≈ O(n2)。
空间复杂度
几乎不需要额外的空间,空间复杂度为O(1)。
稳定性
插入元素的过程中,用的的交换元素方式都是与旁边的元素进行交换,且只有在小于时才交换,因此排序过程不会改变相同元素的相对顺序。故插入排序时稳定的排序算法。