为什么将需要排序数据的二进制搜索比线性搜索更好?


20

我一直听说线性搜索是一种幼稚的方法,并且由于渐近复杂性的提高,二进制搜索的性能要优于线性搜索。但是我从来不明白为什么在二进制搜索之前需要排序时,为什么它比线性搜索更好?

线性搜索为O(n),二进制搜索为O(log n)。这似乎是说二进制搜索更好的基础。但是二进制搜索需要O(n log n)对最佳算法进行排序。因此,二进制搜索实际上不应该更快,因为它需要排序。

我正在阅读CLRS,作者在其中表示,在插入排序中而不是使用朴素的线性搜索方法,最好使用二进制搜索来查找必须插入项目的位置。在这种情况下,这似乎是合理的,因为在每次循环迭代时,都有一个可以应用二分查找的排序列表。但是在通常情况下,对于不能保证我们需要搜索的数据集,由于排序要求,使用二进制搜索实际上并不比线性搜索差吗?

我是否忽略了使二进制搜索比线性搜索更好的实际考虑因素?还是不考虑排序所需的计算时间而认为二进制搜索比线性搜索更好?


6
与许多其他事情一样,这一切都归结为:“这取决于...;)”
Jeff B

如果列表已经排序,您是否认为线性搜索仍然更好?在这里可能要考虑一下。
JB金

3
对于任何想更改标题的人,请不要删除有关排序数据的部分,因为删除它会使这看起来像一个完全不同的问题。
Aseem Bansal

Answers:


53

我是否忽略了使二进制搜索比线性搜索更好的实际考虑因素?

是的-您只需要进行一次O(n log n)排序,然后就可以根据需要多次进行O(log n)二进制搜索,而线性搜索每次都是O(n)。

当然,仅当您实际上对同一数据进行多次搜索时,这才是一个优势。但是“一次编写,经常阅读”的情况很普遍。


如果您仅做一次操作,那么对其进行优化就没什么意义了。

14

基本假设是您不进行一次搜索。

因此,如果您需要多次搜索相同的数据,则只需排序一次即可从二进制搜索中受益。

如果您经常搜索并且有变化的数据,则值得使用已排序的列表,其中将新条目排序到列表中。

因此,当您多次搜索同一列表而不需要求助时,基本上二进制搜索会更好。

当您需要在搜索之前进行每次排序时,这没有任何好处。

请注意,当列表已经排序(或几乎排序)时,有一些排序算法非常快。大多数性能确定都希望使用未排序的列表。


2
如果您经常搜索并频繁插入,则可能会看到更复杂的数据结构(例如,二叉树)。
MarkJ

@MarkJ原始海报的基本问题是关于在列表中搜索。另外,我完全同意您的意见。
Uwe Plonus

7

因为一旦你有一个排序的列表,你不需要重新排序它每次这意味着如果你有超过O(log n)的搜索预先排序将净赚你的增益赢(O(n log n + k log n)VSO(k*n)


5

想象两个电话簿。

一本电话簿的名称按字母顺序排列。要找到所需的条目,请在中间打开,选中该条目,然后根据您是超调还是下调来向前或向后移动。

另一本电话簿的名称按随机顺序排列。要找到所需的条目,请从头开始并继续直到找到所需的条目。

第二本书可以在任何大小合适的城市使用吗?


3

我认为二元搜索相对于线性搜索的价值是上下文相关的。如果您从庞大的无序数据集开始并且仅计划从中抽取少量项目,那么排序和执行二进制搜索将很慢。但是,如果您在应用程序的整个生命周期中都维护有序列表并定期访问它,那么二进制搜索是一种更好的选择。


3

就像许多其他答案一样,二进制搜索确实是更可取的,因为排序步骤只能执行一次,然后实际搜索可以根据需要进行多次。但是,对于n的某些值(即某些输入大小),二进制搜索总是比线性搜索执行得更好(即使是一次运行)。

“临界点”是通过求解渐近复杂性方程来计算的:

n log n + log n = n

正如您在Wolfram Alpha看到的那样n的数值可确保二进制搜索和排序始终比单独的线性搜索快。当然,在您的情况下有效的n实际值取决于许多因素,这些因素可能难以估计。

根据马克·普罗布斯特(Mark Probst)的这篇有趣的文章,其中包括当前处理器的一些不错的深度性能测量:

如果您需要搜索经过排序的整数数组,并且性能确实非常重要,请使用线性搜索(如果数组的大小小于64个元素),而使用二进制搜索(如果大于)。


2

用外行的话来说:

如果您有一个无序的列表,其中包含100亿个项目,而您恰巧正在寻找的项目是最后一个,那么您最终将阅读100亿个项目。

在二进制搜索的情况下,索引只能执行一次。以后可以在正确的位置插入以保持顺序。


2

尽管已经列出了“更好的二进制搜索”的许多充分理由,但我们还可以从用户的角度看一下优点:

尽管您通常可以很好地生活在进行排序插入时数据输入操作之间的等待时间短,但是您希望“搜索”尽可能快。从用户的角度来看,分类插入与二进制搜索结合可提供最佳的用户体验。

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.