为什么java的二分查找里面
int mid=l+((r-l)>>1);要这样写
int mid=l+(r-l)>>1;这样写就不行呢
在 Java 中,+ 和 >> 运算符的优先级是不同的。+ 运算符的优先级比 >> 运算符高。
在二分查找算法中,l + ((r - l) >> 1) 表示计算中间索引 mid 的值。这个表达式的目的是找到左边界 l 和右边界 r 的中间位置。
如果你写成 l + (r - l) >> 1,它会先执行 (r - l),然后再执行位运算 >>。这样会导致错误的结果,因为位运算的优先级比加法运算低。
通过使用括号将 (r - l) 包裹起来,可以确保位运算 >> 在加法运算之前执行,从而得到正确的中间索引 mid 的值。
所以,l + ((r - l) >> 1) 是为了确保正确的运算顺序,以获得准确的中间索引值。
运算优先级不一样,先算加法
不光java这样,c语言也是这样的
第三种方法便是使用我们的位运算符中的右移运算符,a>>1 的意思便是 a / 2^1 。其实第二种方法也是计算机将除法操作转化为位运算的方式来计算,因此二三种方法其实是差不多的,只是方法三在速度上略有领先。
public static void main(String[] args) {
int[] arr = new int[500];
for (int i = 0; i < arr.length; i++) {
arr[i] = i + 1;
}
int L = 0;
int R = arr.length - 1;
int Mid = L + ((R - L) >> 1);
System.out.println(arr[Mid]);
}
根据参考资料,在Java的二分查找中使用 int mid = l + ((r - l) >> 1) 这样的表达式,而不能使用 int mid = l + (r - l) >> 1 这样的表达式。
这是因为Java中的位移运算符的优先级低于加减运算符,如果不使用括号将 (r - l) 进行包裹,那么表达式 int mid = l + (r - l) >> 1 的计算顺序会先执行加法运算,然后再进行位移运算。这样的话,可能会导致对 (r - l) 的结果进行位移运算,而不是对整个 l + (r - l) 的结果进行位移运算。
举例来说,假设 l = 2,r = 5,那么根据表达式 int mid = l + ((r - l) >> 1),执行步骤如下: 1. 计算 (r - l),得到 5 - 2 = 3。 2. 进行位移运算,将 3 右移 1 位,即得到 1。 3. 将 l 和 1 相加,得到 mid = 2 + 1 = 3。
而如果使用表达式 int mid = l + (r - l) >> 1,执行步骤如下: 1. 计算 (r - l),得到 5 - 2 = 3。 2. 执行位移运算,将 3 右移 1 位,即得到 1。 3. 将 l 和 (r - l) 的结果相加,得到 mid = 2 + 3 = 5。
可以看到,这两个表达式的结果是不相同的。在二分查找中,需要确保得到的 mid 是两个边界的中间位置,因此需要使用括号将 (r - l) 进行包裹,确保先进行位移运算,再进行加法运算,从而得到正确的 mid。
因此,使用 int mid = l + ((r - l) >> 1) 这样的表达式是为了确保在二分查找中得到正确的 mid 值。