我是 Python 的新手并试图学习算法,我想问一下,如果我在查看列表时使用low < hi
,为什么它在逻辑上是错误的,正确的逻辑操作是low <= hi
,它阻止的边缘情况是什么。
def binary_search(input_array, value):
"""Your code goes here."""
#O(log(n))
low = 0
hi = len(input_array) - 1
while low <= hi: #why cant it be low < hi
mid = (low + hi)//2
if input_array[mid] == value:
return mid
elif input_array[mid] < value:
print(low, hi)
low = mid + 1
else:
hi = mid - 1
return -1
test_list = [1,3,9,11,15,19,29]
test_val1 = 25
test_val2 = 15
print(binary_search(test_list, test_val1))
print(binary_search(test_list, test_val2))
答案 0 :(得分:5)
假设您只有一个元素[1]
,并且您正在搜索1
。
<
:return -1
因为你只是跳过循环
<=
:返回正确的值
答案 1 :(得分:0)
我们使用<=
而不只是<
,因为如果所需的值恰好是最后一个索引(low=hi
时),我们需要包含一个等号检查那个案子。
答案 2 :(得分:0)
当您的目标是,例如在您的情况下,15:
第一次迭代索引:low == 4
,hi == 6
第二次迭代索引:low == 4
,hi == 4
如果你使用低&lt;在第二次迭代中你不会进入你的循环,因为4&lt; 4返回false
。即使值在索引4上,您的程序也会认为它无法找到该值。
答案 3 :(得分:0)
你可以如果你写过
hi = len(input_array)
while low < hi: # now this works.
...
事实上,通常这就是我通常如何编写这些循环。利用len()
总是比最后一个索引多1的事实,并且仅在索引为<
该值时运行循环。
如果从len(input_array)
中减去1,以便hi
的最大值是数组中的最后一个索引,那么为了破坏最后一个循环元素您需要=
low <= hi
部分
通常情况下(精神上)更容易设置hi = len(input_array)
,即最后一个索引后的1,然后仅在low<hi
时运行循环。
(减少打字,减少心理体操)
在这种情况下,一旦low==hi
我们已经超过了最后一个索引,那么它将超出界限。
&#34;边缘案例&#34;你指的是你想确保在所有元素(索引)上运行循环。 所以,无论如何,您需要查看数组中的最后一个索引/元素。
基本上有两种常用的编码方法,但你不能混淆它们。确保您的最终条件与您的初始条件有关。
您将hi
设置为(数组的长度或数组的最后一个索引)决定您是使用low < hi
还是low <= hi