二进制搜索,使用附近的索引加速

时间:2014-07-30 18:19:52

标签: algorithm binary-search

在对大量数据进行多次二进制搜索时,可以使用搜索附近的值来减小搜索的大小。

举一个简单的例子,假设我们正在搜索范围......

for k in range(n):
    i = binary_search(data, k)
    # operate on `i`

有两个明显的优化。

  • 使用上一个索引作为二分查找中的第一项。
  • 检查数组匹配项中的下一项(如果匹配的可能性很高,则可能很有用)。

但是,由于k是有序的,因此应该可以将先前的索引传递到binary_search和(在大多数情况下),减少将范围平分所需的次数。

所以它看起来像这样:

i_prev = 0
for k in range(n):
    i = binary_search(data, k, index_near=i_prev)
    i_prev = i
    # operate on `i`

是否有一种众所周知的方法可以使用以前找到的索引来优化二进制搜索?

更新

似乎一个好的方法可能是使用二进制搜索的疾驰搜索,使用前一个索引的疾驰搜索来定义范围,然后调用常规二进制搜索功能。 这样做的一个优点是它不会使二进制搜索代码复杂化(它可以保持一个小循环,只做简单的操作)。 这种方法的另一个优点是疾驰搜索可以同时进行两个方向,因此传入的索引可以多于或少于被搜索的索引。 我需要检查一下,可能只需一个奔腾的搜索就足够了,只需搜索到找到的项目,而不是用来定义二进制搜索的限制。

1 个答案:

答案 0 :(得分:0)

这取决于索引的具体使用方式。

最明显的使用方法是根据一些以最后一个元素为中心的高斯外观分布选择中间元素,其宽度由预期的接近度决定。

这将是interpolation search的一种形式,通常使用线性插值来搜索均匀分布的数据。

这样的方法很少使用,因为它们需要深入了解预期的数据分布。这很难付出努力。最多,您可以节省25-30个比较,搜索十亿个元素数组,而如果启发式关闭或数据不像想象的那样,算法可能会使用数百万个比较。

与此同时,基本的二进制搜索已经实现,调试并准备就绪,并保证每次都进行log2(n)比较。