直接插入排序算法的思路非常简单:依次将待排序的数据元素按其关键字值的大小插入前面的有序序列。
细化来说,对于一个有n个元素的数据序列,排序需要进行n-1趟插入操作,如下所示:
第一趟:将第二个元素插入前面的有序子序列中,此时前面只有一个元素,当然是有序的。
第二趟:将第三个元素插入前面的有序子序列中,前面两个元素是有序的。
……
第n-1趟:将第n个元素(也就是最后一个元素)插入前面的有序子序列中,前面的n-1个元素是有序的。
模拟实现如下:
模拟数据为:-56, -21, 56, -21*, 20, 56*, -123, 9, 26, 33
public class InsertSort {
public static void insertSort(DataWrap[] data){
System.out.println("-开始排序-");
int arrayLength = data.length;
//从第二个元素开始判断
for(int i = 1; i < arrayLength; i ++){
//存放当前索引处的数据元素。
DataWrap dw = data[i];
if(data[i].compareTo(data[i-1]) < 0){ //说明当前数据元素比它相邻的前面一个元素要小
int j = i-1;
for(; j >= 0 && data[j].compareTo(dw) > 0; j --){
data[j+1] = data[j];
}
data[j+1] = dw;
}
System.out.println(java.util.Arrays.toString(data));
}
}
public static void main(String[] args){
DataWrap[] data = {new DataWrap(-56,""),
new DataWrap(-21,""),
new DataWrap(56,""),
new DataWrap(-21,"*"),
new DataWrap(20,""),
new DataWrap(56,"*"),
new DataWrap(-123,""),
new DataWrap(9,""),
new DataWrap(26,""),
new DataWrap(33,""),};
System.out.println("-排序前-"+java.util.Arrays.toString(data));
insertSort(data);
System.out.println("-排序后-"+java.util.Arrays.toString(data));
}
}
运行结果为:
直接插入排序的时间效率并不高,在最坏的情况下,所有的元素需要进行比较的次数综合为(0+1+2+……+n-1)= O(n^2),在其他的情况下也要考虑移动的次数,故时间复杂度为O(n^2)。
由于需要一个缓存数据单元,因此空间复杂度为O(1)。
从上图的 56 和 56* 来看,直接插入排序算法是稳定的。
参考资料:《疯狂Java程序员的基本修养》 --李刚
《数据结构(Java版)》 --梁明志编著
《Java算法(第三版,第一卷)》 Robert Sedgewick 著