概述
插入排序就像我们平常玩扑克牌一张一张拿起扑克牌然后排序一样,把数组的所有元素分为两组,已经排序的和未排序的,第一次默认左边第一个是排序好的,然后找到未排序的第一个元素,向已经排序的进行插入。通过倒叙遍历已经排序的元素,依次和待插入的元素进行比较,直到找到一个已经排序的元素小于等于待插入的元素,然后把该待插入的元素放到这个位置,把后面的已经排序好的元素向后移一位
图解
如上图是插入排序的全过程,第一轮,默认最左边的4是已经排序好的,所以待插入的第一个数字是2,2小于4,那么2就放到4的位置,4的位置往后移一位。第二轮,待插入的数字是1,1小于4,1放在4的位置,4的位置后移一位,1小于2,那么1放在2的位置,2的位置往后移一位。第三轮,待插入的数字为10,10大于4,因为4往前的元素都是比4小的,所以10大于4,自然也大于4以前的元素,所以10的位置不用移动。第四轮,待插入的数字为5,5小于10,但5大于4,所以5的位置应该放在10的前面,10往后移一位。最终排序好的顺序为[1,2,4,5,10]
代码
public void sort(int array[]){
//循环控制轮数,第一次待插入的元素是第二位,所以i的初始值为1
for (int i = 1; i < array.length; i++) {
//循环控制每一轮待插入元素和已排序元素比较的次数,从待插入前面到索引为0的元素
for (int j = i; j > 0; j--) {
/**
* 比较待插入的元素,与待插入前那个已排序的元素,注意待插入的元素不能表示为array[i],
* 因为如果有比待插入大的,那么待插入的位置就不是i了,待插入的位置应该表示为j
*/
if(array[j-1] > array[j]){
int temp = array[j-1];
array[j-1] = array[j];
array[j] = temp;
}else{
break;
}
}
}
}
时间复杂度
插入排序的时间复杂度与冒泡排序和选择排序的时间复杂度是一样的第一轮需要找(n-1)次,第二轮需要找(n-2)次,以此类推第(n-1)轮需要找1次,则总共需要 ∑ i = 1 n − 1 ( n − 1 ) = 1 + 2 + 3 + . . . + ( n − 1 ) = n 2 2 − n 2 \sum_{i=1}^{n-1} (n-1)=1+2+3+...+(n-1)=\frac{n^2}{2}-\frac{n}{2} ∑i=1n−1(n−1)=1+2+3+...+(n−1)=2n2−2n次,所以选择排序的时间复杂度为:O( n 2 n^2 n2)