我一直在考虑如何优化二进制搜索。代码如下。 到目前为止我做了什么:
我能想到的就是处理不同的输入。
当搜索的元素超出范围时,即搜索低于最低值或高于最高值的数字时,优化最坏情况(最坏情况之一)。当保证在输入中找不到O(logn)比较时,这将保存O(logn)比较。
int input[15] = {1,2,2,3,4,5,5,5,5,6,7,8,8,9,10};
/*
* Returns index p if a[p] = value else -ve int.
* value is value being searched in input.
*/
int
binary_search (int * input, int low, int high, int value)
{
int mid = 0;
if (!input) return -1;
if (low > high) return -1;
/* optimize worst case: value not in input */
if ((value < input[low]) || (value > input[high]))
{ return -2; }
mid = (low + high)/2;
if (input[mid] == value) {
return mid;
}
if (input[mid] > value) {
return binary_search(input, low, mid -1, value);
} else {
return binary_search(input, mid+1, high, value);
}
}
我能想到的另一个最糟糕的情况是,当搜索的值位于输入或第一个元素的中间时。我认为更广泛的是每次调用binary_search的输入的下限/上限。这也要求算法进行精确的logn比较。
关于我可以专注于改进的其他领域的任何其他建议。我不需要代码,但方向会有所帮助。感谢。
答案 0 :(得分:3)
优化您正在考虑的那种 - 处理特殊情况 - 将不可避免地让您在其他情况下花费更多时间。您的“最坏情况”优化使它们成为最佳情况,但代价是创建其他最坏情况。在这种情况下,你已经将两个案例变为“最佳案例”,并将n/2
个案件变为“最坏情况”,而以前则没有。你已经放慢了其他一切。
(特别是在这种情况下,因为你在每次递归时都检查过低/过高。)
如果您真的希望 - 在您的特定用例 - 搜索主要是搜索过低或过高的值,这可能是个好主意。但是,作为一般的经验法则,最快的实现是最简单的实现。
答案 1 :(得分:2)
Jon Bentley的 Programming Pearls 在优化二进制搜索方面有一个很好的章节。请参阅http://www.it.iitb.ac.in/~deepak/deepak/placement/Programming_pearls.pdf
中的第4章其中一个变体非常高效(请参阅“代码调整”一章中的第87页):
# Search a 1000-element array
l = 0
if x[512] < t: l = 1000 + 1 - 512
if x[l+256] < t: l += 256
if x[l+128] < t: l += 128
if x[l+64] < t: l += 64
if x[l+32] < t: l += 32
if x[l+16] < t: l += 16
if x[l+8] < t: l += 8
if x[l+4] < t: l += 4
if x[l+2] < t: l += 2
if x[l+1] < t: l += 1
p = l + 1
if p > 1000 or x[p] != t:
p = 0 # Not Found