给出了一个排序的数字数组。
这个想法是,对于任何给定的数字,代码需要在数组中找到两个封闭的索引,以便:
array[a] <= query <= array[b]
例如,如果给定的数组为[1, 20, 56, 200]
且数字为67
,则为56 <= 67 <= 200
,结果为[2, 3]
。
我用一个简单的O(n)循环和两个二元搜索变体做了一个小测试,令人惊讶的是,对于低n(~0-100?),循环要快得多。 可以在此处访问该测试:http://jsperf.com/array-search-test/5
有没有办法让这些二进制搜索更优化?这个函数每秒运行数千次,数万次。
答案 0 :(得分:1)
我用一个简单的O(n)循环和两个二元搜索变体做了一个小测试,令人惊讶的是,对于低n(~0-100?),循环要快得多。可以在此处访问该测试:http://jsperf.com/array-search-test/2
首先,这就是大O的作用。在二进制搜索中,有许多操作;顺序数组访问相对较少。
但这并不完全是这里发生的事情。你的基准测试不符合他们的要求。
在标记为“O(n),n = 50”的基准测试中,例如,n仍然是最坏情况-1000。你刚刚运行了50次搜索。但是,由于数组的第十个元素是50,它只会进行50次比较。以下二进制搜索不是这样;他们都从元素500开始。很难公平!
制作一些数组。
答案 1 :(得分:1)
我用一个简单的O(n)循环和两个二元搜索变体做了一个小测试,令人惊讶的是,对于低n(~0-100?),循环要快得多。可以在此处访问该测试:http://jsperf.com/array-search-test/2
当然,与直接迭代的小得多的循环体相比,二进制搜索具有很大的开销。
当参数趋向特定值或无穷大时,big O notation描述“限制行为 [上限] ”是什么提供任何证据来比较两次特定实现的运行。
然而,正如@minitech注意到的那样,你的测试用例存在缺陷,即使在n = 50时,二进制搜索已经比线性搜索更快。 Here's an updated example,它也测试n = 5(线性搜索确实更快)并很好地描绘了图中预期的O(n)
与O(log N)
差异(尽管测试数据呈指数增长( 5 * 10 n )图表是指数与线性的。
有没有办法比二进制搜索更优化?
您可以查看interpolation search。
这个函数每秒运行数千次,数万次。
为什么?您甚至可以更好地构建值的查找表。