插入排序是稳定及内部排序。
思路:每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
就是后一个值比较之后,插入到有序序列。所以这个数组分为2段,有序的和无效的。
仔细观察动态数组,来发现规律。前面的是排序好的,黄色。后面是未排序的浅蓝。比较过程是红色代表待排元素,绿色为当前比较元素。
上核心代码:
第1行 int insertVal = arr[1];//取出一个值,作为待排元素
第2行 int inertIndex = 1 - 1;//比较元素索引
第3行 while (inertIndex >= 0 && insertVal < arr[inertIndex]){
第4行 arr[inertIndex+1] = arr[inertIndex];//数据后移
第5行 inertIndex--;
第6行 }
第7行 arr[inertIndex+1] = insertVal;//inertIndex+1就是待排元素的位置
0,先把第一个元素看成有序数组;
1,从数组取出2个元素,作为待排元素;
2,记录比较元素的索引,也就是取出元素的的前一个;
3,insertIndex >= 0防止数组越界。比较元素大小,前面的数大的情况进入处理
4,处理数据:把数据向后移动。(这个步骤走完,数组中会有2个连续的一样数据),原本是insertVal的位置;
5,inertIndex-1,向前继续做比较,直到退出循环。如果进入while条件insertIndex>=0数组可能发生越界。
6,这个行是}不用解释了。
7,inertIndex+1是待插入位置,为什么呢?因为在第5行,减1,不减1是为了退出循环。
这个步骤就写好了。就是插入排序一次的结果。现在加入for就能遍历数组了。
完整步骤:
public static void insertSort(int[] arr){
for (int i = 1; i < arr.length; i++) {
int insertVal = arr[i];
int inertIndex = i - 1;
while (inertIndex >= 0 && insertVal < arr[inertIndex]){
arr[inertIndex+1] = arr[inertIndex];//数据后移
inertIndex--;
}
arr[inertIndex+1] = insertVal;//先index是位置之前的数据,没有进行交换。{1,xx,xx,4/} xx数据相等
//System.out.println("第"+i+"轮"+ Arrays.toString(arr));
}
}
如果还没明白,按照动态填入数据,dubug看一下。
这里我们用的是直接插入排序,还有二分插入排序(又称折半插入排序),链表插入排序,希尔排序(又称缩小增量排序)。平均来说插入排序算法的时间复杂度为O(n^2)。因而,插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,例如,量级小于千,那么插入排序还是一个不错的选择。