一、什么是直接插入排序
比如说有一个无序的数组:9 3 1 4 2 7 8 6 5,要用直接插入排序算法进行排序。简单的来说,直接插入排序的思想就是把没有排序的数插入有序的序列中。那么,第一步要选择一个数作为有序的序列,一般选择的是第一个数(下标为0的数),比如这里是9,然后从第二个数开始依次往后遍历,并与前面的有序的子序列中的数进行比较,然后插入到对应位置,这一趟排序就结束了,形成了一个新的有序子序列,如下图。
排序思想很简单,但是在实现代码的时候,有时候往往会这样想:记住插入元素的位置,假设是k,然后把k后面的元素整体向后移一位,就完成了本次插入。当然,这样做可以实现,但是代码一般会写三重循环,一般来说,不建议代码超过两重循环。所以,在这里,可以换一种思路,那就是每一次把待插入的元素与有序子序列进行比较时,都从有序子序列最后一个元素开始比较,满足交换条件就进行交换,并继续与前面的数进行比较,直到找到的元素不符合交换条件,则说明当前位置是该元素在有序子序列中的位置,此时,退出内层循环,进入外层循环继续处理待插入的元素,直到处理完所有元素,排序结束。这样实现的话只需要两重循环即可实现。
二、直接插入排序代码
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class InsertSort {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int len = sc.nextInt();
List<Integer> array = new ArrayList<Integer>();
for(int i = 0;i < len;i++) {
int element = sc.nextInt();
array.add(element);
}
insertSort(array);
print(array);
sc.close();
}
/**
* @param array 待排序序列
*/
public static void insertSort(List<Integer> array) {
for(int i = 1;i < array.size();i++) {
int j = i;
while(j > 0 && array.get(j) < array.get(j - 1)) {
int temp = array.get(j);
array.set(j, array.get(j-1));
array.set(j - 1, temp);
j--;
}
}
}
public static void print(List<Integer> array) {
for(int item:array) {
System.out.print(item + " ");
}
}
}
三、直接插入排序时间复杂度
从上面的代码可以看出:当待排序的序列处于有序状态的时候,只需要遍历一次序列不进行交换,所以直接插入排序的时间复杂度最好的情况下是O(n);反之,最坏的情况下时间复杂度为O(n²)。
很显然,直接插入排序是稳定的。