1. /**  * “二分插入排序”,利用二分查找优化插入排序中的定位部分。    
  2. * 《算法导论》,习题2.3-6   
  3. *  Observe that the while loop of lines 5 - 7 of the INSERTION-SORT procedure in    
  4. * Section 2.1 uses a linear search to scan (backward) through the sorted    
  5. * subarray A[1  j - 1]. Can we use a binary search (see Exercise 2.3-5)    
  6. * instead to improve the overall worst-case running time of insertion sort to    
  7. * Θ(n lg n)?  * 本文地址:http://mushiqianmeng.blog.51cto.com/3970029/732333   
  8. *@author lihzh(苦逼coder)    
  9. */   
  10. public class InsertSortWithBinarySearch {  
  11.               private static int[] input = new int[] { 21549867103 };   
  12.               public static void main(String[] args)   
  13.               {         //从数组第二个元素开始排序,因为第一个元素本身肯定是已经排好序的           
  14.                 for (int j = 1; j < input.length; j++)   
  15.                 {// 复杂度 n             //保存当前值               
  16.                     int key = input[j];             //利用二分查找定位位置               
  17.                     int index = binarySearch(input, input[j], 0, j - 1);//复杂度:lgn               
  18.                     //将目标插入位置,同时右移目标位置右边的元素               
  19.                     for (int i = j; i > index ; i--)   
  20.                     {//复杂度,最差情况:  
  21.                         //(n-1)+(n-2)+...+n/2=Θ(n^2)                   
  22.                         input[i] = input [i-1];               
  23.                     }               
  24.                     input[index] = key;           
  25.                 }           
  26.                 /*            
  27.                 * 复杂度分析:            
  28.                 * 最佳情况,即都已经排好序,则无需右移,此时时间复杂度为:Θ(n lg n)            
  29.                 * 最差情况,全部逆序,此时复杂度为Θ(n^2)            
  30.                 * 所以针对2.3-6问题,无法将最差情况的复杂度提升到Θ(n lg n)。            
  31.                 */           
  32.                 //打印数组           
  33.                 printArray();       
  34.               }            
  35.               /**        
  36.               * 二分查找        
  37.               * @param input 给定已排序的待查数组        
  38.               * @param target 查找目标        
  39.               * @param from 当前查找的范围起点        
  40.               * @param to 当前查找的返回终点        
  41.               * @return 返回目标在数组中,按顺序应在的位置        
  42.               */       
  43.               private static int binarySearch(int[] input, int target, int from, int to)   
  44.               {           
  45.                 int range = to - from;         //如果范围大于0,即存在两个以上的元素,则继续拆分           
  46.                 if (range > 0)   
  47.                 {             //选定中间位               
  48.                     int mid = (to + from) / 2;               
  49.                     //如果临界位不满足,则继续二分查找               
  50.                     if (input[mid] > target)   
  51.                     {                   
  52.                         return binarySearch(input,target,from,mid-1);               
  53.                     }   
  54.                     else   
  55.                     {                  
  56.                         return binarySearch(input,target,mid+1,to);               
  57.                     }           
  58.                 }   
  59.                 else   
  60.                 {               
  61.                     if (input[from] > target)   
  62.                     {                   
  63.                         return from;               
  64.                     }   
  65.                     else   
  66.                     {                   
  67.                         return from + 1;                   
  68.                     }               
  69.                 }           
  70.               }            
  71.               private static void printArray()   
  72.               {           
  73.                 for (int i : input)   
  74.                 {               
  75.                     System.out.print(i + " ");           
  76.                 }       
  77.               }    
  78. }