仍然可以将此算法视为二进制搜索算法吗?


14

在执行第二个代码kata(要求您执行五次二进制搜索算法,每次使用不同的方法)时,我提出了一个略有不同的解决方案,其工作方式如下:

如果我有一个长度为100的排序数组,并且看到它的起始字段包含数字200而其终止字段包含数字400,那么作为数学研究人员,我可能会在搜索字段35周围开始搜索编号270,而不是普通二进制搜索算法中的字段50。

然后,如果数组的字段35上的数字是270,则35是我正在搜索的索引。

如果不是这种情况,我可以比较得到的数字(例如280),并重复执行数组下部的操作(所以我有35个字段,起始字段包含200,结束字段包含280),如果我找到的数字大于我要搜索的数字,或者大于数组的上部(例如,我有260个:现在我有65个索引,第一个包含260,最后一个包含400。定向,我会转向如果我得到的数字小于我要搜索的数字,则此子数组的索引4,即整个数组的索引39)。

问题是:可以将此算法视为二进制搜索算法吗?如果没有,它有自己的名字吗?


2
是否使用二进制搜索似乎纯粹是一种见解。本质上,您可以给出的唯一答案是“是的,它与二进制搜索足够接近,可以称之为二进制搜索”或“不,不是。” 争论随之而来。
David Richerby

Answers:


23

我不会将其称为二进制搜索。

它显然类似于二进制搜索,很自然地将其视为二进制搜索的改进。但是,它具有明显不同的算法复杂度特性,插值搜索在假设数据均匀分布的情况下,预期运行时间为O(log(log(n)),但是它通过拥有O(n)最坏情况的运行时间来弥补这一点。

我更喜欢说“二进制搜索的最坏情况运行时间是O(log(n))”,而不是“取决于边界元素的选择,二进制搜索的最坏情况运行时间是O(log(n))”。这意味着我无法将插值搜索归类为二进制搜索算法。


据推测,如果当插值搜索出现严重问题时中断插值搜索,则可以在足够线性的数据上保留O(log n)最差情况和O(log log n)。我的猜测是,诸如“如果在登录n次尝试后仍未找到目标,然后切换到二进制搜索”之类的方法将起作用,但是我懒得证明它。当然,会有一类杀手级输入,其花费时间基本上是二进制搜索的两倍。
史蒂夫·杰索普

这个杀手-的想法很有趣。如果不是允许杀手级输入对搜索产生负面影响(例如,通过在数组末尾附近拆分),我们将“可拆分范围”限制/修剪到数组的第二个三分之一或类似位置,该怎么办?那本来会是log3(n)最坏的情况,但仍然会以log(log)最好的情况出现。
安德鲁·加拉施

1
@SteveJessop请记住,渐进复杂性并不是完整的图景。O(log n)非常快。另外,二进制搜索在每个循环中几乎没有作用。因此,插值搜索的问题已经在于,您需要很长的输入来弥补您在每个循环上要做更多工作的事实。您的建议为此增加了更多工作。如果我不能接受非均匀数据的O(n),我怀疑最好的解决方案是采用纯二进制搜索,而不是某种混合方法。
Taemyr

@SteveJessop:无需切换算法;这可以并行完成。给定范围R,您可以将点P1确定为二进制搜索的常规中点,并使用插值确定P2。现在,您有了三个子范围,其中任何一个都不能大于原始范围的一半。检查对阵双方P1和P2的目标值,而且你知道递归其中三个子范围。
MSalters

17

是的,这被称为插值搜索。有一些警告(取决于您的计算模型和数据的分布),其预期运行时间为,比二进制搜索要好。O(loglogn)


凉。现在的问题是,是否可以将其用于代码kata,但这是我的问题。我发现它比二进制搜索更复杂,但为什么不呢。
user6245072

我在写代码以索引几年前的日志文件时发现过一次。我还发现,对于我的数据而言,插值法和二进制切片法之间的交替步骤比单独使用任一方法要好。我不确定它是否具有名称或已知效果。
尼尔·斯莱特

@NeilSlater对冲插值搜索也许?
史蒂夫·考克斯

@SteveCox:我只是搜索了这个词却什么也没发现。决定要求,作为一个新的问题:cs.stackexchange.com/questions/59750/...
尼尔·斯莱特

-1

我认为正确的术语应该是对二分法的深思熟虑的搜索。

您在平面数组中搜索,随后根据其中数字的平面分布来进行仔细的搜索。

这对应于一个人如何在字典中搜索单词。但是,如果数据分配不规则,则效率可能非常低。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.