排序算法(2):插入排序(Insertion Sort)

390 阅读2分钟

基本思想

从第二个元素开始往后,依次选择哨兵元素和前面的元素比较,如果前一个元素大于该哨兵元素(从小到大排序),则把前面那个元素移动到后一个位置;继续往前比较,直到找某个元素不大于该哨兵元素,则哨兵元素插入到位置上;

算法描述

  • 从第一个元素开始,该元素可以认为已经被排序
  • 取出下一个元素,在已经排序的元素序列中从后向前扫描
  • 如果该元素(已排序)大于新元素,将该元素移到下一位置
  • 重复步骤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中用到插入排序