插入排序是一种最简单直观的排序算法,依次选择待排序元素,往前面的有序序列中插入。
1.代码实现
以java实现为例:
public class InsertSort { public static int[] insertSort(int[] nums) { for (int i = 1; i < nums.length; i++) { int pos = i -1 ; //有序序列的最后一个元素位置 int cur = nums[i]; //保存待排序元素的值 //从有序序列往前遍历,碰到大于当前元素的元素时,则将被比较元素下标往后移动一位 while ( pos >= 0 && nums[pos] > cur) { nums[pos + 1] = nums[pos]; pos--; } nums[pos + 1] = cur; //在遍历中找到适合当前排序元素的位置时,将待排序元素插入数组中 } return nums; } public static int[] insertSort1(int[] nums) { //从第2个元素,即下标1 开始排序,左边是已经排好的有序序列,右边是待排序序列 for (int i = 1; i < nums.length; i++) { //从有序序列的最大值开始向前遍历,与待排序元素比较,直到找到一个适合的位置,跳出循环 for (int j = i; j > 0 && nums[j] < nums[j-1]; j--) { int temp = nums[j]; nums[j] = nums[j-1]; nums[j-1] = temp; } } return nums; } public static void main(String[] args) { int[] nums = new int[] { 9, 8, 7, 6, 5, 4, 3, 2, 10 }; int[] newNums = insertSort(nums); for (int x : newNums) { System.out.print(x+" "); } } }
上面的代码提供的两种写法本质上是一样的。
2.数据运行解析
数据的分解示例如下
[9 8 7 6 5 4 3 2 10] 以第二个元素,即i=1的元素8开始,与左边有序序列[9]进行遍历比较,并且交换 ->[8 9 7 6 5 4 3 2 10] 以第三个元素,即i=2的元素7开始,与左边有序序列[8 9]进行遍历比较,并且交换 ->[8 7 9 6 5 4 3 2 10] ... ->[7 8 9 6 5 4 3 2 10] 以第四个元素,即i=3的元素6开始,与左边有序序列[7 8 9]进行遍历比较,并且交换 ->[7 8 6 9 5 4 3 2 10] ... ->[7 6 8 9 5 4 3 2 10] ... ->[6 7 8 9 5 4 3 2 10] ....
3.复杂度分析
插入排序在序列已经有序的情况下有最好时间复杂度O(n),最差和平均时间复杂度都是O(n²),空间复杂度为T(1)。
4.插入排序和冒泡排序的区别
以 [ 4 3 2 1 ] 序列为例,使用参考资料4中的冒泡排序实现代码
冒泡排序的排序路线为:
4 3 2 1 3 4 2 1 2 4 3 1 1 4 3 2 1 3 4 2 1 2 4 3 1 2 3 4
冒泡排序的思路是,嵌套两层循环,对每个元素开始两两排序,直到比对完序列尾部的两个元素。
插入排序的排序路线为:
4 3 2 1 3 4 2 1 3 2 4 1 2 3 4 1 2 3 1 4 2 1 3 4 1 2 3 4
插入排序的思路是,从第二个元素开始,跟左边的有序序列进行比对,找到合适的位置并插入。
参考资料:
1)https://baike.baidu.com/item/%E6%8F%92%E5%85%A5%E6%8E%92%E5%BA%8F/7214992?fr=aladdin
2)https://www.cnblogs.com/lanhaicode/p/11259509.html
3)https://www.cnblogs.com/AraragiTsukihi/p/6339928.html
4)https://www.cnblogs.com/cykfory/p/14097100.html