今天在编写一些代码时,我遇到了一个情况,这个情况导致我编写了一种我以前从未见过的二进制搜索。这个二进制搜索有一个名称,它真的是一个“二进制”搜索?这种二进制搜索是否有名字?
动机
首先,为了使搜索更容易理解,我将解释其催生创建使用情况。
假设您有一个有序号码列表。系统会要求您查找最接近x的列表中的编号索引。
int findIndexClosestTo(int x);
的呼叫findIndexClosestTo()
总是遵循这个规则:
如果
findIndexClosestTo()
最后的结果是i
,然后指数接近i
有幸成为当前呼叫的结果概率较大findIndexClosestTo()
。
换句话说,这次我们需要找到的索引更可能更接近我们发现的最后一个,而不是更远。
例如,想象一个在屏幕上左右走动的模拟男孩。如果我们经常查询男孩位置的指数,那么他可能就在我们找到他的最后一个地方。
算法
鉴于以上的情况下,我们所知道的findIndexClosestTo()
最后的结果是i
(这实际上是第一次函数被调用,i
默认列表的中间指标,为简单起见,尽管单独的二进制搜索来查找第一个调用的结果实际上会更快),并且该函数已被再次调用。鉴于新号码x
,我们按照这个算法来寻找其索引:
interval = 1;
- 位于
i
我们正在寻找,x
数?如果是这样,请返回i
; - 如果不是,请确定
x
是高于还是低于i
。 (请记住,清单是排序的。) - 移动
interval
指数的方向x
。 - 如果我们在新位置找到了
x
,请返回该位置。 - Double
interval
。 (即interval *= 2
) - 如果我们已经通过
x
,回去interval
指标,设定interval = 1
,进入4
鉴于上述(动机标题下)的概率规则,这在我看来是找到正确索引的最有效方法。你知道更快的方法吗?
我认为这实际上是一个数组而不是一个列表?因为列表上的二进制搜索将是愚蠢的。 – Nemo
我会假设最好的答案将取决于基于i的位置的概率分布是什么。例如,如果有99%的可能性在我的3分之内,那么与其他地方只有0.001%的可能性相比,非常不同的答案会很有用。我认为最佳答案应该是基于概率的分布,以便二分法搜索选择一个点,使得每边都有50%的机会。所以如果你可以定义概率曲线,你可以定义一个很好的算法。 – Chris
@Chris非常好点。如果所有数据点的概率都是相近的,那么这可能会比常规二分查找更差。就我而言,从最后一点开始,概率似乎会呈指数衰减,在这种情况下,我相信这种搜索速度更快。它的插值是 –