插入排序的核心是将标记元素左侧视为有序(即已经排序好的元素),然后用标记元素与左侧元素从右往左进行比较,若比较元素比标记元素大,则两者交换位置,直到左侧比较元素比标记元素小,则循环结束,即将标记元素插入该位置
private long[] a;
private int nElems;
public void insertionSort(){
int in ,out;
//out标记为未排序最左端的元素
for(out = 1;out < nElems;out++){
long temp = a[out]; //
in = out;
while(in>0 && a[in-1] >=temp){
a[in] = a[in-1]; //若指针指向元素-1大于指针指向元素,则交换位置
--in; //左边指针继续向左移
}
a[in] = temp; //标记元素插到指针指向位置
}
}
最外层循环,out从1开始,与0号元素进行比较并插入,即视为0号元素为有序,后面以此类推。
插入排序的算法效率:
在第一次排序,最多比较一次,
在第二次排序,最多比较两次
。。。
最后一次最多,一共比较n-1次(n为数组长度即元素个数)
所以–>
1+2+3+…+n-1=n*(n-1)/2
然而,平均每次真的比较的次数只有一半,所以除以2得到n*(n-1)/4
复制的次数大致等于比较的次数,然而,复制和比较的时间耗费不同,所以相对随机数据,这个算法比冒泡排序快一倍,比选择排序略快。
但是时间级还是O(n2)。
但是如果数据基本有序,那么while的条件基本为假,所及成了一个简单的一次循环,执行n-1次。这种情况下,时间复杂度为O(n)。