基本思想
从第二个元素开始往后,依次选择哨兵元素和前面的元素比较,如果前一个元素大于该哨兵元素(从小到大排序),则把前面那个元素移动到后一个位置;继续往前比较,直到找某个元素不大于该哨兵元素,则哨兵元素插入到位置上;
算法描述
- 从第一个元素开始,该元素可以认为已经被排序
- 取出下一个元素,在已经排序的元素序列中从后向前扫描
- 如果该元素(已排序)大于新元素,将该元素移到下一位置
- 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
- 将新元素插入到该位置后
- 重复步骤2-5
演示
代码实现
public static void sort(int[] array) {
for (int i = 1; i < array.length; i++) {
int index = i;
int val = array[index];
while (index > 0 && val < array[index - 1]) {
array[index] = array[index - 1];
array[index - 1] = val;
index--;
}
}
}
时间复杂度
插入排序最优的时间复杂度O(n)
若初始状态是正序的,一趟扫描即可完成排序。所需的关键字比较次数C达到最小值:C=n-1
插入排序最差的时间复杂度O(n^2)
若初始状态是反序的,需要进行n-1趟排序。每趟排序要进行n-i次关键字的比较(1≤i≤n-1)在这种情况下,比较次数达到最大值:Cmax=N(N-1)/2 = O(N^2)
平均时间复杂度为O(N^2)
空间复杂度
最优的空间复杂度,同样,就是不需要借用第三方内存空间,则复杂度为0
最差的空间复杂度就是开始元素逆序排序,每次都要借用一次内存,按照实际的循环次数,为O(N)
平均的空间负杂度为:O(1)
优点与缺点
- 优点:稳定,快
- 缺点:比较次数不一定,比较次数越少,插入点后的数据移动越多,特别是当数据总量庞大的时候
测试记录
待补充
源码
暂时未发现在开源框架或jdk中用到插入排序