一、什么是插入排序?
插入排序(Insertion Sort),是指以插入的方式为待排序的元素寻找合适的位置,从而实现排序的一种排序算法。插入排序的过程有点类似于玩扑克牌时,右手从牌堆中抓起一张牌时,会按照牌面数字大小,将其插入左手牌中合适的位置,这样最终所有牌即可有序排列。
二、插入排序的排序过程
如上文所提,插入排序就像玩牌时给扑克牌排序,不同点在于玩牌时有“左手”和“牌堆”两组元素,其中左手代表有序,即已排序,牌堆中的牌看做无序且未排序。而插入排序算法对数组进行排序时只有一组元素。
插入排序和前面所讲的选择排序这两种算法就有一个巧妙之处:将元素“分组”,即在原有数组中提取子数组来分别表示未排序元素和已排序元素。假设原始数组共有n个元素,那么有序数组初始为0个元素,无序数组为n个元素,每次从无序数组中取出一个元素,然后插入其中合适位置,最终整个成为一个有序数组。
下面我们一起看一下插入排序的具体实现过程(以下依然按照升序的排列方式)。
首先我们拿到一个待排序的数组(牌堆):
1.将数组第一个元素放入“有序数组”,其余元素看做“无序数组”(摸第一张牌),开始循环;
2.取“无序数组”中第一个元素至“有序数组”中,并放入合适位置(摸牌,插入合适位置);
从这一轮开始插入时就需要依次比较以最终确定插入位置。
3.继续取“无序数组”中的元素至“有序数组”中,并放入合适位置(摸牌,插入左手中合适位置);
4.重复第3步的操作,直至“无序数组”中所有元素全部插入“有序数组”。
三、代码实现
插入排序的原理比较简单,但是具体插入哪个位置,如何判断和交换位置,使用代码实现还是要认真思考一下的。
import java.util.Arrays;
/**
* @ClassName InsertionSortDemo
* @Description 插入排序算法
* @Author noobDgz
* @Date 2023/4/4 23:08
* @Version 1.0
*/
public class InsertionSortDemo {
public static void main(String[] args) {
int[] nums = {6, 9, 2, 5, 3, 7};
System.out.println("排序前原始数组: " + Arrays.toString(nums));
insertionSort(nums);
System.out.println("排序后的数组: " + Arrays.toString(nums));
}
private static void insertionSort(int[] arr) {
for (int i = 1; i < arr.length; i++) {//外层循环直接从1开始,即设arr[0]为有序,因为后面还有比较,所以不影响结果
int temp = arr[i];//将”无序数组“中要插入左边“有序数组”的值取出存为一个临时变量,防止连续交换位置时数据丢失
int j;//这里定义j是为了扩大j的作用域,后面赋值会用到j下标
/*内层循环:
如果“有序数组”中的每一个元素都小于temp即要插入的值,则有序数组前面不做任何位置改变;
如果“有序数组”中的某个元素大于temp即要插入的值,该元素后移一位;
*/
for (j = i; j > 0; j--) {//内层循环从i开始,递减
if (arr[j-1] < temp) {
break;
}
arr[j] = arr[j-1];//将前一个元素值赋给后一个元素,即该元素后移一个位置
}
arr[j] = temp;//内层循环结束,此时将temp插入选定的位置。由于元素后移,已经为temp腾出位置;若没有元素后移则temp原地踏步,说明初始位置就是其最终归宿
}
}
}
运行结果:
上述代码也有可以优化的地方或者不同写法。
四、Ending
以上就是插入排序算法的具体实现,和选择排序的共同之处也是其精华所在,就是在数组内部“设”了子数组,从而将有序和无序元素区分开来。希望本文能帮到和我一样的小白,如有不当欢迎指正。