基本介绍
插入排序是对一对序列以插入的方式寻找该元素的适当位置,以达到排序的目的。
基本思想
把n个待排序的元素看成一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含n-1个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次和有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。
案例分析
初始数据: [ 3, 1, -1, 2, 4]
- 将数组开始分为 {3} ,{1,-1,2,4},然后将1和3进行比较,3比1大,则将1插入3前面,一轮插入排序后,数组变成{1,3},{-1,2,4}
- 此轮插入的数为-1,首先将-1和3进行比较,-1比3小,继续比较1和-1,-1比1小,一轮插入排序后,数组变成{-1,1,3},{2,4}
- 此轮插入的数为2,首先将2和3进行比较,2比3小,继续比较,发现2比1大,结束此轮遍历,数组变成{-1,1,2,3},{4}
- 此轮插入的数为4,首先比较3和4,4比3大,遍历结束,插入排序结束,数组变成{-1,1,2,3,4}
代码分步实现
int[] arr = new int[]{3, 1, -1, 2, 4};
//开始将数组分为有序和无序列表 {3} {1,-1,2,4};待插入的数据为 1
int insertVal = arr[1];
int j = 0;
//从右到左倒叙遍历有序列表,进行比较,如果插入值比倒叙遍历中的值大,
// 则跳出遍历,并将待插入的值插入当前下标的位置
// 如遍历到待插入的值比有序列表中的值小,则将当前下标的值后移
for (j = 0; j >= 0; j--) {
if (insertVal < arr[j]) {
arr[j + 1] = arr[j];
} else {
break;
}
}
//此处为j+1 是此轮循环后,j进行了j--操作
arr[j+1] = insertVal;
System.out.println("第一次插入排序后:" + Arrays.toString(arr));
insertVal = arr[2];
for (j = 1; j >= 0; j--) {
if (insertVal < arr[j]) {
arr[j + 1] = arr[j];
} else {
break;
}
}
arr[j+1] = insertVal;
System.out.println("第二次插入排序后:" + Arrays.toString(arr));
insertVal = arr[3];
for (j = 2; j >= 0; j--) {
if (insertVal < arr[j]) {
arr[j + 1] = arr[j];
} else {
break;
}
}
arr[j+1] = insertVal;
System.out.println("第三次插入排序后:" + Arrays.toString(arr));
insertVal = arr[4];
for (j = 3; j >= 0; j--) {
if (insertVal < arr[j]) {
arr[j + 1] = arr[j];
} else {
break;
}
}
arr[j+1] = insertVal;
System.out.println("第四次插入排序后:" + Arrays.toString(arr));
运行结果:
第一次插入排序后:[1, 3, -1, 2, 4]
第二次插入排序后:[-1, 1, 3, 2, 4]
第三次插入排序后:[-1, 1, 2, 3, 4]
第四次插入排序后:[-1, 1, 2, 3, 4]
排序代码实现
将发步骤的代码整合中两层循环,代码如下:
for (int i = 1,j; i < arr.length; i++) {
int insertVal = arr[i];
for (j = i - 1; j >= 0; j--) {
if (insertVal < arr[j]) {
arr[j + 1] = arr[j];
} else {
break;
}
}
arr[j + 1] = insertVal;
System.out.println("第"+i+"轮插入排序后:"+Arrays.toString(arr));
}
运行结果:
第1轮插入排序后:[1, 3, -1, 2, 4]
第2轮插入排序后:[-1, 1, 3, 2, 4]
第3轮插入排序后:[-1, 1, 2, 3, 4]
第4轮插入排序后:[-1, 1, 2, 3, 4]
上述代码在内层循环中结合我们都会执行这条语句:
arr[j + 1] = insertVal;
当我们在没有数据进行交换的时候,是可以不需要进行赋值操作的;代码改动如下:
for (int i = 1,j; i < arr.length; i++) {
int insertVal = arr[i];
for (j = i - 1; j >= 0; j--) {
if (insertVal < arr[j]) {
arr[j + 1] = arr[j];
} else {
break;
}
}
if (j+1 != i){
arr[j + 1] = insertVal;
}
System.out.println("第"+i+"轮插入排序后:"+Arrays.toString(arr));
}