基本思想
通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应的位置并插入。对于给定的一组记录,初始时假定第一个记录自成一个有序序列,其余记录为无序序列。接着从第二个记录开始,按照记录的大小依次将当前处理的记录插入到其之前的有序序列中,直到最后一个记录插到有序序列中为止。
算法描述:
假定Lenght是数组A的长度,
首先假设第一个元素被放置在正确的位置上,这样仅需从1到Lenght-1范围内对剩余元素进行排序。
对于每次遍历,从0 到i-1范围内的元素已经是有序的。
每一次从0 到 i 的遍历:通过扫描前面已排序的子列表,找到相应的位置并插入。
将A[j]赋值给临时变量key。
向左遍历数组,比较这个目标值key与A[i-1]、A[i-2]的大小,依次类推。
这个比较过程在小于或等于目标值的第一个元素(A[i])处停止,或者在列表开始处停止(i=0)。
在A[i]小于前面任何已排序元素时,后一个条件(i=0)为真,
因此,这个元素会占用新排序子列表的第一个位置。
在扫描期间,大于目标值key的每个元素都会向右滑动一个位置(A[j]=A[i-1])。
确定正确位置目标值后及(i的位置), key值就会被复制到这个位置。
与选择排序不同的是,插入排序将数据向右滑动,并且不会执行交换。
排序过程:
Java 实现
public class TestJava {
public static void main(String[] args) {
int[] array = new int[]{3, 2, 4, 6, 7, 9, 8, 1, 5};
for (int i = 1; i < array.length; i ++) {
int key = array[i];
int j = i - 1;
while (j >= 0 && array[j] > key) {
array[j + 1] = array[j];
j --;
}
array[j + 1] = key;
}
for (int ceil : array) {
System.out.println(ceil);
}
}
}
效率问题
空间复杂度O(1)
时间复杂度O(n2)
数组在已排序时,插入排序效率的最好情况运行时间为O(n);
插入排序最坏情况运行时间和平均情况运行时间都为O(n2)。