在二分搜索中计算中点索引

时间:2014-01-13 20:52:26

标签: c search

因此,在二进制搜索中计算mid的正确方法是mid = low + ((high - low) / 2),以便处理溢出错误。

我的实现使用无符号的64位变量,我从来没有看到过我的数组变得太大而导致溢出的情况。我是否仍然需要使用上述实现,或者我可以使用mid = (low + high) / 2

这里的最佳做法是什么?

4 个答案:

答案 0 :(得分:6)

如果没有溢出的可能性,计算中点的溢出安全方法在技术上是不必要的:如果您愿意,可以使用不安全的公式。但是,无论如何,将它保留在那里可能是一个好主意,以防你的程序有一天被修改以打破你的假设。我认为添加单个CPU指令以使您的代码面向未来是对代码可维护性的巨大投资。

答案 1 :(得分:5)

查看此文章Nearly All Binary Searches and Mergesorts are Broken

更好的实践(今天)

  

可能更快,可以说明确的是:    6:int mid =(低+高)>>> 1;

之后:

  

在C和C ++中(你没有>>>运算符),你可以这样做:    6:mid =((unsigned int)low +(unsigned int)high))>> 1;

最后:

  

2008年2月17日更新:感谢芬兰诺基亚研究中心工程人员Antoine Trux指出最初提出的C和C ++修正案(第6行)不能保证符合相关的C99标准(国际标准 - ISO / IEC - 9899 - 第二版 - 1999-12-01,3.4.3.3),其中说如果添加两个有符号的数量并获得溢出,则结果是未定义的。在这方面,较旧的C标准,C89 / 90和C ++标准都与C99相同。现在我们已经做了这个改变,我们知道程序是正确的;)

最重要的是,总会出现无效的情况

答案 2 :(得分:0)

Don Knuth的方法通过位掩码完美地工作,不会出现溢出:

return (low & high) + ((low ^ high) >> 1)

答案 3 :(得分:0)

<块引用>

因此,在二进制搜索中计算 mid 的正确方法是 mid = low + ((high - low) / 2),以便处理溢出错误。

这是不正确的。考虑low = 18 * pow(10, 18)high = 1 * pow(10, 18)mid = (low + high) / 2 和您的方法都溢出,产生 276627963145224192 而不是正确的 9500000000000000000