进行二进制搜索时如何设置中间元素?

时间:2018-07-17 15:56:22

标签: java c# algorithm data-structures

这听起来可能是非常幼稚的问题。请原谅我。我正在处理涉及二进制搜索的问题。我学到的一般方法是

 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;
}

3 个答案:

答案 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,在我们范围的中间