一、基本思路
基本思路: 把n个待排序元素看成一个有序表和一个无序表,开始时有序表中只含有一个元素,无序表中包含n-1个元素,排序过程中每次从无序表中取出一个元素,把它依次与有序表中的元素进行比较,并插入到有序表的适当位置,使之成为新的有序表。
简单来说: 就是先将第一个元素看成一个有序表,从第二个元素开始,依次 插入到对应的位置,直到所有元素都插入完成。
举例:
有一序列为:101,34,119,1要求按升序排列
先把101看作一个有序表,从第二个元素开始,依次插入到有序表中适当的位置。
- 第一轮(把34插入到有序表[101]中)
(1)34,101,119,1(34小于101,所以将101后移,34插入到第一个位置) - 第二轮(把119插入到有序表[34,101]中)
(1)34,101,119,1(119大于101,所以将119插入到101后面,即不改变) - 第三轮(把1插入到有序表[34,101,119]中)
(1)1,34,101,119(1小于119、101、34,所以将这三个元素依次后移,将1插入到第一个位置)
这样4个数经过3轮插入序列就确定下来了。
二、算法分析
时间: 在插入排序中,当待排序数组是有序时,是最优的情况,只需当前数跟前一个数比较一下就可以了,这时一共需要比较N- 1次,时间复杂度为 O(n);最坏的情况是待排序数组是逆序的,此时需要比较次数最多,总次数记为:1+2+3+…+N-1,所以,插入排序最坏情况下的时间复杂度为O(n²)。
空间: 可以看到,插入排序的元素后移以及插入操作都是在序列上直接进行的,无需另外开辟空间,所以空间复杂度为O(1)。
算法 | 平均时间 | 最好情形 | 最坏情形 | 稳定度 | 空间复杂度 | 备注 |
---|---|---|---|---|---|---|
插入排序 | O(n²) | O(n) | O(n²) | 稳定 | O(1) | 大部分元素有序时较好 |
三、代码实现
import java.util.Arrays;
/**
* @author dankejun
* @create 2020-04-28 12:13
*/
public class InsertSort {
public static void main(String[] args) {
int arr[] = {101,34,119,1};
insertSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void insertSort(int[] arr) {
int insertVal;
int insertIndex;
for (int i = 1; i < arr.length ; i++) {
insertVal = arr[i];
insertIndex = i - 1;
while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
arr[insertIndex + 1] = arr[insertIndex];
insertIndex--;
}
if (insertIndex + 1 != i) {
arr[insertIndex + 1] = insertVal;
}
System.out.printf("第%d轮:%s\n",i,Arrays.toString(arr));
}
}
}
测试序列: int arr[] = {101,34,119,1};
测试结果: