一、基本介绍
插入排序是将 n 个待排序的元素看成一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含 n-1 个元素,排序过程中每次从无序表中取出第一个元素,依次与有序表进行比较,将它插入到合适的位置,形成一个新的有序表。
二、排序过程
对数组[100 , 20 , 80 , 8 ] 从小到大排序过程如下:
1. 初始状态为 [**100** , 20 , 80 , 8 ] ,将第一个元素看做有序的。
2. 第一次插入
- 从数组 arr[1] = 20 开始,然后与待插入位置 0 进行比较,20小于100,交换位置,形成一个新的数组 [ **20 , 100** , 80 , 8 ]
3. 第二次插入
- 从数组 arr[2] = 80 开始在有序表 [20 , 100] 中寻找位置。第一次寻找时,待插入位置 100大于80,于是继续往前寻找,然后发现 20小于80,插入元素 80 形成新的数组 [ **20 , 80 , 100 **, 8 ]
4. 第三次插入
- 从数组 arr[3] = 8 开始在有序表 [20 , 80 , 100 ] 中寻找位置。第一次寻找时,待插入位置 100大于8;于是继续往前寻找,然后发现 80 大于 8;继续向前寻找,20 大于 8,将 8 插入到第一个位置,得到有序数组 [ **8 , 20 , 80 , 100 ** ]
这个时候数组变排好序了。可以看出,当数组中的元素个数为 m 时,需要进行 m-1 趟排序。如下图所示,绿色表示有序,灰色表示无序。
三、代码实现
public static void insertSort(int[] arr) {
if (arr == null || arr.length < 2) {//数组为空或者长度为1直接返回
return;
}
int insertIndex = 0;
int insertVal = 0;
for (int i = 1; i < arr.length; i++) {//从第二个位置开始循环判断插入
insertIndex = i - 1;//待插入元素位置索引
insertVal = arr[i];//保存待插入元素的值
while (insertIndex >= 0 && arr[insertIndex] > insertVal) {//当索引小0或者待插入元素的值小于待插入位置的值时候跳出循环
arr[insertIndex + 1] = arr[insertIndex];//大的值后移
insertIndex--;
}
arr[insertIndex + 1] = insertVal;//将待插入元素插入到对应位置
}
}