有很多方法可以在递归中编写二进制搜索算法 但是如果在列表中找到值,它们都返回True,否则返回False。 是否有任何可能的方法在递归中编写二进制搜索算法 之后我会得到已建立价值的指数?更重要的是 - 它还会 在log(n)?我不是在寻找内置功能!
到目前为止,这是我的代码:
def bin_search(val,L):
if len(L) == 1:
if L[0] == val:
return True
else:
return False
else:
hi = len(L)
lo = 0
mid = (hi + lo)//2
if val == L[mid]:
return True
elif val > L[mid]:
bin_search(val,L[mid + 1:])
elif val < L[mid]:
bin_search(val,L[:mid + 1])
答案 0 :(得分:0)
def binaryIndex(L, x, offset=0):
if not L:
return -1 # item does not exist in the list
elif L[len(L)//2] == x:
return offset + len(L)//2
elif L[len(L)//2] > x:
return binaryIndex(L[:len(L)//2], x, offset)
else:
return binaryIndex(L[(len(L)//2)+1:], x, offset+(len(L)//2)+1)
输出:
>>> binaryIndex([0,1,2,3,4], 0)
0
>>> binaryIndex([0,1,2,3,4], 1)
1
>>> binaryIndex([0,1,2,3,4], 2)
2
>>> binaryIndex([0,1,2,3,4], 3)
3
>>> binaryIndex([0,1,2,3,4], 4)
4
>>> binaryIndex([0,1,2,3,4], 5)
-1
是的,这仍然是O(log(n))
答案 1 :(得分:0)
您现有的函数至少有两个主要问题:它不会return
递归调用的值,这意味着如果它完成,它通常会返回None
;它使用错误的边界来对列表进行切片,这意味着它有一半的时间以无限递归结束。
如果你修复了这些,那么你所要做的就是返回索引而不是True,以及其他东西(例如-1,或者引发异常)而不是False。这意味着递归调用将索引放入切片而不是整个列表,但是他们知道偏移量并且可以调整它。
所以,首先:
if len(L) == 1:
if L[0] == val:
# return True
return 0
else:
# return False
raise ValueError('not found')
else:
hi = len(L)
lo = 0
mid = (hi + lo)//2
if val == L[mid]:
# return True
return mid
elif val > L[mid]:
# return bin_search(val,L[mid + 1:])
return mid + 1 + bin_search(val,L[mid + 1:])
elif val < L[mid]:
# no change here, because the offset is 0
return bin_search(val,L[:mid])
就是这样。很明显,这是完全相同的递归调用序列,唯一的额外工作是在不到一半的情况下添加mid + 1
,因此它仍然具有相同的复杂性。