算法回顾系列第四篇:折半插入排序
------------------------------------------------
折半插入排序
基本原理:
类似直接插入排序,把n个待排序的元素看成为一个有序表和一个无序表,每趟取无序表中的第一个元素插入有序表中。
但在插入的过程中不是与有序表中的每个元素去比较,而是使用二分查找算法确定插入的位置。
程序实现:
public static void binaryInsertSort(int[] input){
//从数组第二个元素开始排序,因为第一个元素本身肯定是已经排好序的
for(int i=1;i<input.length;i++){
//保存当前值
int key = input[i];//利用二分查找定位位置
int index = binarySearch(input,input[i],0,i-1);
//将目标插入位置,同时右移目标位置右边的元素
for (int j=i; j>index; j--){
input[j] = input[j-1];
}
input[index] = key;
}
//打印数组
System.out.println(Arrays.toString(input));
}
/**
* 二分查找
* @param input 已排序的待查数组.
* @param target 需要插入的数.
* @param from 当前数组查找范围的起点(0).
* @param to 当前数组查找范围的终点(length-1).
* @return 返回目标在数组中,按顺序应在的位置.
*/
private static int binarySearch(int[] input, int target, int from, int to){
int range = to-from;//如果范围大于0,即存在两个以上的元素,则继续拆分
if(range > 0){
//选定中间位
int mid = (to+from)/2;
//如果临界位不满足,则继续二分查找
if (input[mid] > target){//中间位置的元素值大于目标元素
return binarySearch(input,target,from,mid-1);//在0至中间位置查找
}else{//中间位置的元素值小于目标元素
return binarySearch(input,target,mid+1,to);//在中间位置到末尾位置查找
}
}else{
if (input[from] > target){
return from;
}else{
return from + 1;
}
}
}
上面程序中:
找到插入位置后需要将后面的元素每个都后移一个位置。
二分查找算法可以参考我的算法回顾系列文章第三篇。
性能分析:
最坏时间复杂度:O(n^2)。
空间复杂度:1。
稳定性:稳定的排序。