一、基本思路
插入排序的基本思路是把n个待排序的元素看成一个有序列表和一个无序列表,一开始有序列表只有一个元素,无序列表有n-1个元素,排序过程每次从无序列表中拿出第一个数与前面的有序表中的元素进行大小比较,并且将这个元素插入到有序列表中的适当位置,使之成为新的有序列表。
顾名思义简而言之就是把前面已经排好序的元素看成一个列表,再把剩下的元素看成一个新的列表,每次把剩下元素的第一个元素插入到有序列表中合适的位置,知道第n个元素。
二、图解
下面给出一个图解事例,帮助大家理解。
三、代码实现
理解了上面的思路分析和图解事例之后,用Java实现算法很简单。
//插入排序
public static void insertSort(int[] arr) {
int insertVal = 0;
int insertIndex = 0;
for(int i = 1; i < arr.length; i++) {
//定义待插入的数
insertVal = arr[i];
insertIndex = i - 1; // 即arr[1]的前面这个数的下标
// 给insertVal 找到插入的位置
// 说明
// 1. insertIndex >= 0 保证在给insertVal 找插入位置,不越界
// 2. insertVal < arr[insertIndex] 待插入的数,还没有找到插入位置
// 3. 就需要将 arr[insertIndex] 后移
while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
arr[insertIndex + 1] = arr[insertIndex];// arr[insertIndex]
insertIndex--;
}
// 当退出while循环时,说明插入的位置找到, insertIndex + 1
//这里我们判断是否需要赋值
if(insertIndex + 1 != i) {
arr[insertIndex + 1] = insertVal;
}
}
四、总结和优化
由此看出,插入排序的时间复杂度是(n^2)
但是如果后面的元素比较小时,比如下面(4、2、5、7、1)这个待排序数列,1在最后面,后移的次数明显增多,对算法的效率会有影响,需要进行优化,其实优化有就是所谓的希尔排序,下一章将讲解希尔排序。