递归二进制搜索算法 - Python

时间:2014-01-15 18:34:47

标签: python

有很多方法可以在递归中编写二进制搜索算法 但是如果在列表中找到值,它们都返回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])

2 个答案:

答案 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,因此它仍然具有相同的复杂性。