这听起来可能是非常幼稚的问题。请原谅我。我正在处理涉及二进制搜索的问题。我学到的一般方法是
set low = 0, set high = array.Length - 1
while(low < high)
mid = (low+high)/2
if (array[mid] == element) return mid
if (array[mid] > element) set start = mid +1
if array[mid] < element ) set high = mid
请注意我设置中点的方式。但是我看到的一些示例/解决方案设置了不同的中间点,我无法解决这个问题。请参见下面的代码段。任何解释设置mid = l +(r-l)/ 2意味着什么的方法将不胜感激。
int BinarySearch(int A[], int l, int r, int key)
{
int m;
while( l <= r )
{
m = l + (r-l)/2;
if( A[m] == key ) // first comparison
return m;
if( A[m] < key ) // second comparison
l = m + 1;
else
r = m - 1;
}
return -1;
}
答案 0 :(得分:2)
两种情况下的目标都是找到中间元素。
(low + high) / 2
:将左和右索引的总和除以2得到中点。问题在于总和可能溢出。
如果总和是一个 even 数字,我们选择较低的数字。示例-左侧和右侧为[2, 5]
-我们选择中间值为3
l + (r - l) / 2
:找到左右索引之间的差并将其除以2。然后将其添加到左索引以找到中点。通过一个示例将其可视化可能会更容易。
示例:[5, 11]
-> (11 - 5) / 2 = 3
现在此间隔的中间距离左索引3个位置或跃点。因此,添加左索引以找到中间元素的索引5 + 3 = 8
答案 1 :(得分:1)
完成此技巧是为了避免整数溢出问题。
(i)使用不带符号的右移运算符
int mid=(high+low)>>>1
或
(ii)int mid=low +(high-low)/2
(low+high)/2
, Integer.MAX_VALUE
将溢出,并且您将得到错误的结果或RuntimeException
您可以阅读Josh Bloch的这篇文章: https://ai.googleblog.com/2006/06/extra-extra-read-all-about-it-nearly.html
答案 2 :(得分:1)
中间等于左值的起始索引加上左右之间的范围除以二。
说我们的范围是5到10。
5 +(10-5)/ 2 == 5 + 5/2 == 5 + 2.5 == 7.5,在我们范围的中间