当前位置: 首页 > 知识库问答 >
问题:

这个二进制搜索是如何工作的?

汪臻
2023-03-14

我在一本书《做二进制搜索》中看到了这个方法,但无论我怎么尝试,我都无法理解它是如何工作的。有人能确切地向我解释一下它是如何工作的吗?

这本书的解释无助于:

这个想法是在我们靠近目标元素时跳跃并减慢速度。变量k和b包含数组中的位置和跳跃长度。如果数组包含元素x,搜索后x的位置将在变量k中。该算法的时间复杂度为O(log n),这是因为对每个跳转长度而言,同时循环中的代码最多执行两次。

我不明白的是k是如何在数组中迭代的?我们如何确保它不会跳过目标的索引?我尝试用示例值跟踪这个程序的一些运行,但无法找出k遵循的模式,以确定目标x是否存在于数组中。

int k = 1;
for (int b = n/2; b >= 1; b /= 2) {
while (k+b <= n && t[k+b] <= x) k += b;
}
if (t[k] == x) {} // x was found at index k

注意:我很清楚“通用二进制搜索算法”(使用开始、中间和结束索引的算法)

共有1个答案

诸葛砚
2023-03-14

b是当前位置的跳跃长度。如您所见,bn/2开始,每一步都被2除,直到达到1为止。

现在,对于每个b,记住b在for循环中的每一步都被2除以,我们运行一个time循环,在这个循环中我们将b添加到我们的当前位置,也就是k>。我们将b添加到k检查中,以获得两个条件:k b小于n(以确保我们不会出界),并且t[k b]小于而不是我们正在搜索的x。

这实际上意味着,对于每个b,我们将b添加到k中,直到它超过我们正在寻找的值为止。此时,while循环中断,我们除以b以更慢的速度接近目标,希望我们不会越过它。

最后的b只有一个,以确保我们不会错过x,如果它只是k位置后的下一个元素

这样看,一辆车正朝着一个目标狂奔。起初,汽车以最大速度行驶,当它接近目标时,它会逐渐减速,直到到达目标。

与传统的二进制搜索的不同之处在于,在传统的二进制搜索中,我们遍历目标,然后回来,一遍又一遍,在每次迭代中,我们减少来回的步骤。在这个算法中,我们只前进(从不超过目标),但是我们通过除以b来不断减少步骤的长度。

 类似资料:
  • 二进制搜索是一种快速搜索算法,运行时复杂度为Ο(log n)。 这种搜索算法的工作原则是分而治之。 为使此算法正常工作,数据收集应采用排序形式。 二进制搜索通过比较集合的最中间项来查找特定项。 如果匹配发生,则返回项目的索引。 如果中间项大于项,则在中间项左侧的子阵列中搜索项。 否则,在中间项右侧的子阵列中搜索项。 该过程也在子阵列上继续,直到子阵列的大小减小到零。 二进制搜索如何工作? 要使二进

  • 给定二叉查找树(BST)和整数val的根。 在BST中找到该节点的值等于val的节点,并返回以该节点为根的子树。如果这样的节点不存在,则返回null。 为什么'ans=root'不起作用??

  • 问题内容: 我知道Go有一个包含搜索功能的程序包,但这是出于教育目的。我一直在尝试在Go中实现二进制搜索算法,但无法使其正常工作。 这是我的代码: 它总是打印。为什么? 问题答案: 二进制搜索的逻辑是合理的。唯一的问题是您忘记了将每个递归调用的结果分配给和。 当前,您有以下这些递归调用: 您只需要分配结果:

  • 我正在尝试实现一个二叉查找树,但是“搜索”函数对于除了根之外的每个条目都返回了错误的值。 该函数应返回其值与键参数匹配的节点的地址,如果节点不存在,则返回 NULL。 当我运行代码时,我得到以下内容: 我知道每个节点的“左”和“右”指针链接正确,因为“delAll”函数成功删除了所有节点。 将“cout”语句添加到“search”函数表明该函数似乎返回了正确的地址。为什么从主主调用时会打印错误的地

  • 本文向大家介绍在Javascript二进制搜索树中搜索值,包括了在Javascript二进制搜索树中搜索值的使用技巧和注意事项,需要的朋友参考一下 我们将使用BST的属性在其中查找元素。首先让我们看一下搜索的迭代实现-  示例 在此功能中,我们从根作为currNode开始,然后将我们的数据与currNode的数据进行比较。如果找到匹配项,则返回true,否则我们将继续根据数据与currNode数据

  • 我试着删除二叉查找树的节点,当我打印出来的时候,我得到的结果实际上不是这个删除,实际上可以删除二叉树本身的任何键。 我是二进制搜索树的新手。有人能帮我写代码吗?我们将感谢您的帮助。 谢谢 完整代码