为什么我们在二分搜索中写lo +(hi-lo)/ 2?

时间:2014-08-29 15:23:20

标签: c++ algorithm binary-search

我正在阅读二进制搜索...我知道找到中间值的传统方式就像

mid=(hi+lo)/2

但我也看到,为了避免溢出,中间值的计算就像那样

mid=lo+(hi-lo)/2

但为什么?我找不到实际的原因。任何人都可以举例说明理由吗? 它与其他问题不同,因为其他问题没有我想要的答案......

2 个答案:

答案 0 :(得分:20)

假设您正在使用32位unsigned int作为索引搜索4000000000元素数组。

第一步看起来似乎搜索到的元素(如果存在)将位于上半部分。 lo的值为2000000000hi的值为4000000000

hi + lo溢出并生成小于预期6000000000的值。它实际上产生6000000000-2 32 。因此,(hi + lo) / 2是一个很小的值。它甚至不在lohi之间!

从那时起,搜索将是错误的(可能会认为该元素即使在那里也不存在)。

相比之下,即使使用此示例中的极值,lo + (hi - lo) / 2也始终计算hilo之间的索引,正如算法所预期的那样。

答案 1 :(得分:4)

从数学上讲,它们是等价的。

在计算机术语中,mid=(hi+lo)/2的操作较少,但mid=lo+(hi-lo)/2是首选,以避免溢出。

假设您搜索的项目接近数组的末尾,则hi+lo几乎为2*size。由于size几乎与最大索引一样大,2*size因此hi+lo可能会溢出。