算法回顾系列第四篇:折半插入排序

------------------------------------------------

折半插入排序

 

基本原理:

类似直接插入排序,把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。

稳定性:稳定的排序。