插入排序将序列分为两部分,一部分为有序的,一部分为待排序的。每趟将一个待排序的关键字按照其大小插入到有序序列的适当位置上,直到所有待排关键字都被插入到有序序列中为止。
具体流程:
- 将开头元素视作已排序
- 执行下述处理,直到待排序部分消失
- 取出待排序部分的开头元素赋值给变量temp
- 在已排序部分,将所有比temp大的元素向后移动一个单位
- 将已取出的元素temp插入空位。
以数组{8, 3, 1, 5, 2, 1}进行插入排序,流程如下图所示:
参考代码如下:
public static void insertSort(int[] num){
if (num == null)
return;
//因为给定的数组一般都是从下标为0开始的,如果将其作为哨兵,需要将其先整体往后挪,排完序后再挪回来
//所以声明一个常数空间来存储元素,但是这样无法防止数组越界,需要自己判断
for (int i=1; i<num.length; i++){
if (num[i] < num[i-1]){
int temp = num[i]; //复制为哨兵
int j = i-1;
//加入约束条件j>=0,并且要将其放在前面,不然数组越界
while (j>=0 && temp<num[j]){
num[j+1] = num[j];
j--;
}
num[j+1] = temp;
}
}
}
一般在衡量排序算法时,我们会考虑其时间复杂度,空间复杂度和稳定性。
插入排序法算法稳定;时间复杂度最好情况下为O(n),此时序列本身有序;最坏时间复杂度为O(n^2);平均时间复杂度为O(n^2);空间复杂度为O(1)。
参考文献: 《挑战程序设计竞赛》