插入排序Insertion Sort
时间复杂度:O(n^2)
每次都与它前一个位置的元素作比较,如果小于它前一个位置的元素就做交换。
/**
* 每次比较都进行交换,消耗时间长
* @param arr
* @param n
*/
public void insertSort(E[] arr, int n){
for(int i = 1 ; i < n ; i ++){
//第0个元素放在那就是有序的
//寻找元素arr[i]合适的插入位置
for(int j = i ; j > 0; j --){
if(arr[j].compareTo(arr[j-1]) < 0){
E temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
}
else{
//有提前终止第二层循环的机会,比选择排序应该快一些
break;
}
}
}
}
存在的问题:
插入排序有提前终止第二层循环的机会,理论上应该比选择排序要快一些,但是因为每一次与前面的元素进行比较时,如果小于前面的元素就进行交换,一次插入就可能会有多次的比较交换,一次交换就有三次赋值,实际消耗时间可能比选择排序长。
插入排序优化:
增加一个变量,等于当前待插入的元素,每次与前面的值进行比较,直到找到正确的位置,再进行交换。
(插入排序就像我们玩的扑克牌一样,每次把抓到的牌插入到正确的位置。)
/**
* @param arr
* @param n
*/
public void insertSort2(E[] arr, int n){
for(int i =1;i<n;i++){
//寻找元素arr[i]合适的插入位置
E e = arr[i];
int j ;//j保存元素e应该插入的位置
for(j = i; j >0; j--){
//前面的元素是否比e大,比e大,说明该位置还不是e最终的位置
if(arr[j-1].compareTo(e)>0){
//把前面的元素复制到后面这个元素(把前面的元素往后一下)
arr[j] = arr[j-1];
}else{
break;
}
}
//不再使用交换语句,而是使用赋值语句
arr[j] = e;
}
}