基本思想
给定一个长度大小为N的数组arr,我们做的就是将这个序列分为两部分,前面是有序的,后面是无序的。然后我们依次取后面的一个元素和前面的元素进行比较,如果符合排序,就插入到前面的有序序列中。
具体的细节我建议大家去看代码中的逻辑,跟着代码走一遍,会理解的更加清楚,话不多说上代码
代码示例
import java.util.Arrays;
import java.util.Random;
/**
* 插入排序算法
*/
public class InsertSort {
public static void insertSort(int []arr){
if(arr == null || arr.length<2){
return;
}
for(int i = 1;i<arr.length;i++){
for(int j=i-1;j>=0;j--){
if(arr[j]>arr[j+1]){
swap(arr,j,j+1);
}
}
}
}
/**
* 在数组中交换两个变量的值
* @param arr 数组
* @param i 坐标位序i
* @param j 坐标位序j
*/
public static void swap(int[] arr,int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
/**
* 随机生成数组序列
* @param maxSize 序列最大长度
* @param maxValue 序列最大值
* @return
*/
public static int[] generateRandomArray(int maxSize,int maxValue){
Random random = new Random();
int[] arr = new int[(int) random.nextInt(maxSize+1)];
for(int i = 0;i<arr.length;i++){
arr[i] = random.nextInt(maxValue + 1);
}
return arr;
}
public static void main(String[] args) {
int[] arr = generateRandomArray(10,10);
System.out.println(Arrays.toString(arr));
insertSort(arr);
System.out.println(Arrays.toString(arr));
}
}
细节
在外循环这一步,与我之前写的选择排序、冒泡排序不同,这里的起点不再是0,而是1,原因是当我们把序列分为有序和无序时,第一个有序序列只有i=0一个值,默认有序,因此我们从i=1开始,与前面的有序序列进行比较。终点是小于arr.length,而不是arr.length-1,原因是这里我们需要拿到最后一个值,与前面的有序数组进行比较,也就是说,这里的外循环的意思不再是简单的执行N-1趟了。希望大家写代码的时候可以迅速想到这一点。
内循环的起点为i-1,也就是让节点i依次与前面的元素进行比较,终止条件是i>=0,很好理解,不能越界嘛。
复杂度分析
时间复杂度:
第一趟执行1次比较
第二趟执行2次比较
…
第N-1趟执行N-1次比较
等差数列求和,总的比较次数为(N-1)+(N-2)+…+2+1,因此时间复杂度为O(
N
2
N^{2}
N2)
空间复杂度:
只用到了有限个常熟级空间,因此空间复杂度为O(1)
尾注
留下笔记,只为方便回忆,如有侵权,还请联系,如有错误,还请纠正。陆续更新,还请关注。