递归二进制搜索算法-Python

递归二进制搜索算法-Python,python,Python,在递归中编写二进制搜索算法有很多方法 但是,如果在列表中找到值,它们都返回True,否则返回False。 是否有任何可能的方法在递归中编写二进制搜索算法,以便 之后,我将获得所建立值的索引?更重要的是,它还会继续吗 在日志中(n)?我不是在寻找内置函数 以下是我的代码,到目前为止: def bin_search(val,L): if len(L) == 1: if L[0] == val: return True else: re

在递归中编写二进制搜索算法有很多方法 但是,如果在列表中找到值,它们都返回True,否则返回False。 是否有任何可能的方法在递归中编写二进制搜索算法,以便 之后,我将获得所建立值的索引?更重要的是,它还会继续吗 在日志中(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])
def bin_搜索(val,L):
如果len(L)==1:
如果L[0]==val:
返回真值
其他:
返回错误
其他:
hi=len(L)
lo=0
mid=(高+低)//2
如果val==L[mid]:
返回真值
elif val>L[中间]:
bin_搜索(val,L[mid+1:])
elif val
输出:

>>> 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))

您现有的函数至少有两个主要问题:它不
返回递归调用中的值,这意味着如果它完成,通常会返回
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])
如果len(L)==1:
如果L[0]==val:
#返回真值
返回0
其他:
#返回错误
提升值错误('未找到')
其他:
hi=len(L)
lo=0
mid=(高+低)//2
如果val==L[mid]:
#返回真值
中途返回
elif val>L[中间]:
#返回bin_搜索(val,L[mid+1:])
返回mid+1+bin_搜索(val,L[mid+1:])
elif val

就这样。显然,这是在执行完全相同的递归调用序列,唯一的额外工作是在不到一半的情况下添加
mid+1
,因此它仍然具有相同的复杂性。

Python的标准库中已经有了实现。搜索代码库以查看其工作方式。您可以在退出时重建索引,也可以传递一个列表和一对索引,而不是一个切片。向我们展示您的代码,我们就可以向您展示如何调整它。@Abhijit:实际上,并不返回索引,只需使用它们即可。它不是递归的,它是一个循环。所以它证明了这是可能的,但并没有直接告诉你怎么做function@user3045065:内置和stdlib函数很有用,因为它们都随附。当然,在CPython中,有些是用C实现的,而不是用Python实现的……但是在这种情况下,您可以随时查看。
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])