【问题标题】:binary search pattern implementation details/usage questions二分搜索模式实现细节/使用问题
【发布时间】:2016-05-31 19:54:55
【问题描述】:

以下 SO url 为 Big O 表示法提供了一些很好的真实示例:

What does O(log n) mean exactly?

我对以下为二分搜索提供的示例特别感兴趣:

"O(log n): 给定一个人的名字,通过在你还没有搜索到的书的一半左右随机选择一个点来找到电话号码,然后检查这个人的名字是否在那个位置点。然后在书中人名所在的部分重复这个过程。(这是对人名的二分搜索。)"

关于这个我有一些不清楚的地方:

  • 教科书式的二分搜索是否从在数组的确切中间点开始搜索?如果数组中有偶数个项目,教科书的二分搜索算法应该随机选择较低或较高的项目吗?

  • 教科书的二分搜索是对特定数据点进行中途搜索,还是搜索数据点的集群组以提高效率?或者二分搜索模式是否支持这些方法中的任何一种?

  • 二分查找能否应用于已排序或未排序的数组?还是总是建议在执行二进制搜索之前以编程方式对数组进行排序?

【问题讨论】:

    标签: algorithm big-o binary-search


    【解决方案1】:

    该示例无法正确解释某些内容。首先,假设它是一个字典,您正在其中搜索名称。假设您正在搜索“John”。第 (n/2) 页为您提供以字母 L 开头的名称(例如第 X 页)。因此,您忽略从该页面开始的所有内容,因为您知道该页面和其他页面无法包含您正在搜索的内容。现在,您的搜索集减少到从第 1 页到第 X 页的搜索。继续执行相同的步骤,每次选择页面时忽略搜索集的 n/2 项。

    所以,根据我给出的解释:

    1.) 如果 n 是偶数/奇数,只需选择 n/2 得到的值。您将在下一次迭代中考虑第 1 页到 (n/2)-1(或)第 (n/2)+1 到 n 页。因此,这里没有跳过任何元素的风险。

    2.) 在每次迭代中,您都会考虑整个搜索集。从迭代 i 到 i+1 的搜索集之间的区别在于, 元素的数量将减少一半。

    3.) BS 的先决条件之一是我们应该考虑排序的项目列表。这就是我在解释中使用字典的原因。

    而这个操作是 O(logn) 的原因是因为你每次将项目列表减少一半。想象一下,列表中有 32 个项目。在这里找到答案所需的迭代次数为 5(第一次迭代中 32 次减少到 16 次,第二次迭代中 16 次减少到 8 次等)。可以看到,32和5的关系是log 32 (base 2) = 5

    【讨论】:

    • 使用以下例程识别起始索引是否有任何问题?:var startIndex = Math.Round(itemCount/2);
    • 如果 itemCount 是一个整数(它应该是一个整数,因为它将是一个索引),你不应该担心四舍五入的数字。
    • 但如果我的集合有 5 个项目,那么以下 startIndex 例程将返回 2.5: var startIndex = Math.Round(itemCount/2);我无法访问索引为 2.5 的集合,因此 Math.Round 似乎涵盖了偶数或奇数项目的两种情况。 Math.Round 不是更好的选择吗?你能写出你通常用来识别 startIndex 的例程吗?
    • 试试这个:int itemCount = 5; int x = (itemCount/2);打印出 x 的值,看看你得到了什么。这会让你更清楚。
    • 如果我们从中间索引和更高的索引中搜索所有项目,那么(如果未找到项目)我们搜索中间索引以下的所有项目,那么我们将在 1-2 次搜索调用中找到该项目。我的印象是二进制搜索模式涉及某种类型的递归集合划分,它将连续划分剩余的集合以进行搜索。二分搜索模式真的像拆分一个集合然后执行 1-2 次搜索那么简单吗?
    猜你喜欢
    • 2015-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-06
    • 1970-01-01
    相关资源
    最近更新 更多