以下的代码就是二分查找的java实现,如下
- 代码1-1
- public static int buggyBinarySearch(){
- int low = 0 ;
- int high = a.length - 1 ;
- while(low <= high){
- int mid = (low + high)/2; //******************
- int midVal = a[mid];
- if(midVal < target) //在数值较大的一边
- low = mid + 1;
- else if(midVal > target)
- high = mid - 1;
- else
- return mid;//第一次就找到
- }
- return -1;
- }
或许你已经注意到了,方法的命名buggyBinarySearch(),这是一段存在Bug的二分查找代码,Bug位于这一行
- int mid = (low + high)/2; //******************
如果low和high的和大于Integer.MAX_VALUE(在java中是2 23 -1),计算就会发生溢出,使(low + high)成为一个负数,然后被2除,结果当然仍是负数。
那么有没有改进的办法呢?如果有,代码改怎么改?有2个方法可以解决这个问题,
第一是改用减法实现,而不是用加法,代码如下:
- int mid = low + (high - low)/2;
第二个方法是,如果你掌握位运算,这种方法或许更快,代码如下:
- int mid = (low + high) >>> 1;
二分查找的思想如此简单,而又有多少人(我就是其中一个)在写代码时真正考虑了这些问题,是否
考虑这些潜在的问题,每一次对简短的、精确的、经典的代码的学习,我们学会的不仅仅是一个算法,而是一种思想。