在这里,我有一个数组:
{1,3,5,6,7,8,9,11,13,14,15}
足够简单。但是,我们将使用二进制搜索来搜索整数3所在的索引。计算机需要进行多少次比较?
看,我认为这是三次比较,但不知何故,这是不正确的。有人会解释计算机需要进行多少次比较,为什么?我对编程比较陌生,而且我没有很好地理解这个概念。
答案 0 :(得分:4)
该序列上的二进制搜索算法将如下进行。所以,我们正在寻找3
,我们将序列中间的元素与3进行比较。
{1, 3, 5, 6, 7, 8, 9, 11, 13, 14, 15}
=?
3
它们不相等,所以采用左子序列,我们将3与其中间元素进行比较,即
{1, 3, 5, 6, 7}
=?
3
它们仍然不相等,然后我们转到左子序列,即
{1, 3}
我们与中间元素进行比较,但我们有一个大小为2的列表!如果我们选择作为中间元素1,那么我们需要进行另一次比较,即我们需要递归到正确的子序列,即{3}
。在那种情况下,我们将进行4次比较!
但是等等,还有另外一个技巧,你还需要在每次迭代或递归调用时检查基本情况,并将这些帐户用于其他比较!
答案 1 :(得分:2)
二进制搜索依赖的事实是,数组已经排序。
您可以使用中间的元素,您可以使用mid = (left + right) / 2
计算该元素,并将array[mid]
与您正在搜索的元素进行比较,在这种情况下为3。
如果array[mid]
大于3,则必须在左边3。
如果它更小,那么如果它包含在数组中则3将在右侧。
这会产生一个新的较小间隔,大小只有一半。
你的尺寸减半,直到你达到1号的间隔。这些是log n
步,log n
是你可以将n
除以2直到达到1的次数。
看看this answer,它解释了数学细节。重要的是要注意使用的对数具有2的基数。
答案 2 :(得分:1)
比较次数高于一系列数字的简单二进制细分,因为您需要检查<,=和>当前节点。
伪代码:
for node,
if x < node, search left
else if x > node, search right
else x == node (stop searching)
这取决于您检查的顺序。该程序需要检查每个节点最多两次比较。由于x ==节点仅用于一个节点,因此将编码作为默认条件的编码意义最大(因为分支预测,您希望首先测试更多可能的分支)。
因此,在第一遍,节点8,它将发现(x <8)为真,移动到节点5,找到(x <5)为真,然后向左移动。
现在,左边的内容可能是1或3(因为它是一个未填充的子树,它可能是其中之一)。如果它是1,那么移动到节点1找到(x <1)假,然后找到(x> 1)为真,然后移动到节点3.
在这个阶段我们在节点3处。我们发现(x <3)假,然后检查(x> 3),也是假,因此推断x == 3.最短路径是4检查,但如果我们不得不停在节点1(同样可能),我们这样做是6次检查。
请注意,我故意将此偏向于检查(x <节点),如果您以不同的顺序检查它们,那么平均比较计数将会上升。例如如果先检查相等性,则添加其他不需要的检查:
for node,
if x == node (stop searching)
else if x < node, search left
else x > node, search right
所以在第一遍,节点8,它会找到(x == 8)假,然后找到(x <8)为真,然后找到(x == 5)假,然后找到(x <5) )是,然后(50%几率)转到节点1,找到(x == 1)假,然后找到(x <1)假,然后找到(x == 3)真。所以5或7都是这样检查的。如果您首先搜索正确的分支,那么您将获得不同的度量。