二分查找——出现溢出问题

算法描述:

  1. 前提:有已排序数组 A(假设已经做好)

  2. 定义左边界 L、右边界 R,确定搜索范围,循环执行二分查找(3、4两步)

  3. 获取中间索引 M = Floor((L+R) /2)

  4. 中间索引的值 A[M] 与待搜索的值 T 进行比较

    ① A[M] == T 表示找到,返回中间索引

    ② A[M] > T,中间值右侧的其它元素都大于 T,无需比较,中间索引左边去找,M - 1 设置为右边界,重新查找

    ③ A[M] < T,中间值左侧的其它元素都小于 T,无需比较,中间索引右边去找, M + 1 设置为左边界,重新查找

  5. 当 L > R 时,表示没有找到,应结束循环

代码实现:

public class BinarySearch {

   public static void main(String[] args) {
       int[] array = {1, 5, 8, 11, 19, 22, 31, 35, 40, 45, 48, 49, 50};
       int target = 48;
       int idx = binarySearch01(array, target);
       System.out.println(idx);

  }

   /**
    * 1. 前提:有已排序数组 A(假设已经做好)
    * 2. 定义左边界 L、右边界 R,确定搜索范围,循环执行二分查找(3、4两步)
    * 3. 获取中间索引 M = Floor((L+R) /2)
    * 4. 中间索引的值 A[M] 与待搜索的值 T 进行比较
    * ① A[M] == T 表示找到,返回中间索引
    * ② A[M] > T,中间值右侧的其它元素都大于 T,无需比较,中间索引左边去找,M - 1 设置为右边界,重新查找
    * ③ A[M] < T,中间值左侧的其它元素都小于 T,无需比较,中间索引右边去找, M + 1 设置为左边界,重新查找
    * 5. 当 L > R 时,表示没有找到,应结束循环
    *
    * @param array
    * @param target
    * @return
    */
   private static int binarySearch01(int[] array, int target) {
       int L = 0, R = array.length - 1, M;
       while (L <= R) {
           M = (L + R) / 2;
           if (array[M] == target) {
               return M;
          } else if (array[M] > target) {
               R = M - 1;
          } else {
               L = M + 1;
          }
      }
       return -1;
  }
}

出现整数溢出实例:

假设a为左边界索引,b为右边界索引,且为整数最大值-1,c为中间索引

        int a = 0;
       int b = Integer.MAX_VALUE-1;
       int c = (a+b)/2;
       // 假设目标值在中间索引的右边
       // 重新设置中间索引,此时出现整数溢出
       c = (c+1+b)/2;
       System.out.println(c);

打印出c的值为:-536870913

解决溢出:

方法一:

M = (L + R) / 2; 将改成:M = L+(R-L)/2;

方法二:

 M = (L + R) / 2; 

根据位运算可以改写成:

M = (L + R) >>>1
 
posted @ 2023-05-07 21:22  小謝同學  阅读(78)  评论(0编辑  收藏  举报