【发布时间】:2017-08-05 12:57:45
【问题描述】:
这里,我有一个数组:
{1、3、5、6、7、8、9、11、13、14、15}
足够简单。但是,我们将使用二进制搜索来搜索整数 3 在哪个索引上。计算机需要进行多少次比较?
看,我认为这是三个比较,但不知何故这是不正确的。谁能解释一下计算机进行了多少次比较,为什么?我对编程比较陌生,对概念的理解不是很好。
【问题讨论】:
标签: java
这里,我有一个数组:
{1、3、5、6、7、8、9、11、13、14、15}
足够简单。但是,我们将使用二进制搜索来搜索整数 3 在哪个索引上。计算机需要进行多少次比较?
看,我认为这是三个比较,但不知何故这是不正确的。谁能解释一下计算机进行了多少次比较,为什么?我对编程比较陌生,对概念的理解不是很好。
【问题讨论】:
标签: java
对该序列的二分搜索算法将按如下方式进行。所以,我们正在寻找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 次比较!
但是等等,还有另一个技巧,您还需要在每次迭代或递归调用时检查基本情况,这些用于其他比较!
【讨论】:
二分查找依赖于数组已经排序这一事实。
你取中间的元素,你可以用mid = (left + right) / 2 计算它,并将array[mid] 与你正在搜索的元素进行比较,在本例中为 3。
如果array[mid] 大于 3,则 3 必须在左侧。
如果它更小,如果它包含在数组中,则 3 将在右侧。
这会产生一个新的更小的间隔,大小只有一半。
将大小减半,直到达到大小 1 的间隔。这些是 log n 步数,log n 是您可以将 n 除以 2 直到达到 1 的次数。
看看this answer,它解释了数学细节。需要注意的是,使用的对数以 2 为底。
【讨论】:
比较的次数比一个数字范围的简单二进制细分要高,因为需要检查当前节点。
伪代码:
for node,
if x < node, search left
else if x > node, search right
else x == node (stop searching)
这取决于您进行检查的顺序。该程序需要检查每个节点最多两个比较。由于 x == 节点仅用于一个节点,因此将其作为默认条件最具有编码意义(由于分支预测,您希望首先测试更有可能的分支)。
所以在第一遍,节点 8,它会找到 (x
现在,左边的可能是 1 或 3(因为它是一个未填充的子树,它可能是任何一个)。如果是1,则移动到节点1 find (x 1) true,然后移动到节点3。
在这个阶段,我们在节点 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 right 个分支,那么您会得到不同的测量结果。
【讨论】: