算法-插入排序
插入排序
条件:
- 必须是有序的集合
- 顺序是从小到大排列
插入排序
问题分析:
问题1:一个有序的数组,我们往里面添加一个新的数据之后,如何继续保持数据有序呢?
答:我们只要遍历数组,找到数据应该插入的位置将其插入即可。
这是一个动态排序的过程,即动态的往有序集合中添加数据,我们可以通过这种方法保持集合中的数据一直有序。而对于一组静态数据,我们也可以借鉴上面的插入方法,来进行排序,于是就有了插入排序。
问题2:那么插入排序具体是如何实现上面的思想来实现排序的呢?
答:(1) 我们可以将数组中的数据模拟分为两个区间,已排序区间
和未排序区间
。
(2) 初始已排序区间
只有一个元素,也就是数组的第一个元素。
(3) 插入算法的核心思想:
取未排序区间的元素,然后在已排序区间找到合适的位置将其插入,并且保证已排序区间的数据一直是有序的。重复这个过程,直到未排序区间的数据元素为空,算法结束。
插入排序
与冒泡排序
的区别:
- 在冒泡排序中,经过每一轮的排序处理之后,数组后端的数都是排好序的。
- 在插入排序中,经过每一轮的排序处理之后,数组前端的数都是排好序的。
解题思路:
伪代码:
// 定义区间:已排序区间和未排序区间
for(外层循环i:未排序区间取值){
未排序区间第i个值{num[i]};
for(里层循环j:对已排序区间进行遍历比较[与未排序区间的值进行比较]
&& 判断条件符合则进行插入[条件:num[j] > num[i]]){
// 注意:里层循环的第③条件,对已排序区间进行遍历效率最快的方法:从后往前,故:j--
// 符合条件则意味着已排序区间最大的值 < 未排序区间的值,所以此时将最大值定为目前的值,在进行遍历
num[j+1] = num[j];// 详情见分解图
}
// 不符合条件:[已排序区间最大的值 > 未排序区间的值],直接插入后面
已排序区间最后插入值;
}
图解
代码如下:Java编写
import java.util.Arrays;
public class InsertionSort {
private static void insertionSort(int[] nums) {
for (int i = 1, j, n = nums.length; i < n; ++i) {
int num = nums[i];//第i次比较的值
for (j = i - 1; j >=0 && nums[j] > num; --j) {
nums[j + 1] = nums[j];// 往后移一位
}
nums[j + 1] = num;// 插入
}
}
public static void main(String[] args) {
int[] nums = {1, 2, 7, 9, 5, 8};
insertionSort(nums);
System.out.println("执行结果:" + Arrays.toString(nums));
}
}
执行结果:
执行结果为:[1, 2, 5, 7, 8, 9]