我编写了以下代码,在列表或元组target
中对值collection
进行二进制搜索。
def binary(collection, target):
"""Binary search
Takes a sorted list or tuple, collection, then searches for target
Returns -1 if item isn't found. """
length = len(collection)
minimum = 0
maximum = length - 1
while minimum <= maximum:
pivot = (minimum + maximum) // 2
if collection[pivot] is target:
return pivot
elif collection[pivot] > target:
minimum = pivot + 1
else:
maximum = pivot - 1
return -1
如您所见,在target
中找不到collection
时,该函数返回-1。无论我做了什么,函数都返回-1。
>>> test = [1, 2, 3, 4, 5, 6]
>>> binary(test, 5)
-1
>>> binary(test, 1)
-1
是什么导致了这个问题?
答案 0 :(得分:4)
你有这种情况倒退:
elif collection[pivot] > target:
切换它并进行搜索:
elif collection[pivot] < target:
对于它的价值,我通过在搜索中添加打印输出来了解这一点,看看发生了什么。如有疑问,请添加打印输出:
>>> binary([1, 2, 3], 1)
(min=0, max=2, pivot=1)
(min=2, max=2, pivot=2)
^ Oops
# After fixing...
>>> binary([1, 2, 3], 1)
(min=0, max=2, pivot=1)
(min=0, max=0, pivot=0)
顺便说一句,内置的bisect module执行二进制搜索。你不必自己写,除非你是为了教育价值。
答案 1 :(得分:1)
除了将条件测试更正为elif collection[pivot] < target:
之外,您还使用“是”运算符来测试您是否找到了目标项目:
if collection[pivot] is target:
您应该使用“==”代替:
if collection[pivot] == target:
使用“is”测试两个东西是否实际上是同一个对象。在Python中,通常会将小型字符串和整数对象存储和回收,因此这可能有效。但是,在大多数情况下,它不会:
>>> a='abc'
>>> id(a)
2129839392
>>> b='ab'
>>> b+='c'
>>> id(b)
2129963136
>>> a
'abc'
>>> b
'abc'
>>> binary([a],a)
0
>>> binary([a],b)
-1