以下的代码就是二分查找的java实现,如下

  • 代码1-1
 
  1. public static int buggyBinarySearch(){ 
  2.      int low = 0 ; 
  3.      int high = a.length - 1 ; 
  4.      while(low <= high){ 
  5.     int mid = (low + high)/2; //******************
  6.     int midVal = a[mid]; 
  7.     if(midVal < target) //在数值较大的一边 
  8.          low = mid + 1
  9.     else if(midVal > target) 
  10.          high = mid - 1
  11.     else 
  12.          return mid;//第一次就找到 
  13.      } 
  14.      return -1
  15.       
  16. }

或许你已经注意到了,方法的命名buggyBinarySearch(),这是一段存在Bug的二分查找代码,Bug位于这一行

 
  1. int mid = (low + high)/2//****************** 

如果low和high的和大于Integer.MAX_VALUE(在java中是2 23 -1),计算就会发生溢出,使(low + high)成为一个负数,然后被2除,结果当然仍是负数。

那么有没有改进的办法呢?如果有,代码改怎么改?有2个方法可以解决这个问题,

第一是改用减法实现,而不是用加法,代码如下:

  •  
 
  1. int  mid = low + (high - low)/2

第二个方法是,如果你掌握位运算,这种方法或许更快,代码如下:

  •  
 
  1. int mid = (low + high) >>> 1

二分查找的思想如此简单,而又有多少人(我就是其中一个)在写代码时真正考虑了这些问题,是否

考虑这些潜在的问题,每一次对简短的、精确的、经典的代码的学习,我们学会的不仅仅是一个算法,而是一种思想。