Python 正确的二进制搜索算法

Python 正确的二进制搜索算法,python,algorithm,binary-search,Python,Algorithm,Binary Search,可以用以下方式编写二进制搜索的实现吗 def binarySearching(sortedArr,v): if len(sortedArr)>=1: mid = len(sortedArr)//2 if v<sortedArr[mid]: return binarySearching(sortedArr[:mid],v) elif v>sortedArr[mid]:

可以用以下方式编写二进制搜索的实现吗

    def binarySearching(sortedArr,v):
    if len(sortedArr)>=1:
        mid = len(sortedArr)//2
        if v<sortedArr[mid]:
            return binarySearching(sortedArr[:mid],v)
        elif v>sortedArr[mid]:
            return binarySearching(sortedArr[mid+1:],v)
        else:
            return mid
        return None
def二进制搜索(sortedar,v):
如果len(分拣机)>=1:
mid=len(分拣机)//2
如果VSortedar[mid]:
返回二进制搜索(分类器[mid+1:],v)
其他:
中途返回
一无所获
我不明白为什么我们需要为算法指定


编辑:多亏了@Stef,这个实现是不正确的,因为mid不是原始数组,而是子数组

当您仅使用数组/列表时,必须指定
低和高
。在每次迭代中,您都会在
low..high
范围内处理列表的一部分


您的实现生成子列表,因此它不需要明确的范围定义(但是这个子列表的形成是免费的吗?

使用二进制搜索算法时,每一步都将搜索区域缩小一半

在传递同一数组进行搜索并仅更改搜索区域时,可以指定
low
high


传递
low
high
的替代方法是传递数组的一部分,但在python中,这意味着每次对数组(列表)进行切片时,都会创建另一个对象(即切片列表),这是内存效率低下的问题。

比较
binarySearch
的这两种实现。第一个是你的,第二个是我的

在您的版本中,您正在向递归调用传递“切片”,即子数组的整个副本。在我的版本中,所有递归调用都访问同一个数组而不复制它,相反,只有
low
high
作为参数传递

#使用切片,即子阵列的副本
def二进制搜索(分拣机,v):
#打印(分拣机)
如果len(分拣机)>=1:
mid=len(分拣机)//2
如果VSortedar[mid]:
返回二进制搜索(分类器[mid+1:],v)
其他:
中途返回
其他:
一无所获
#使用低指数和高指数
def otherBinarySearching(分拣机,v):
def辅助(低、高、v):
#打印(低、高、分拣机[低:高])
如果高>低:
中间=(高+低)//2
如果v<分拣机[mid]:
辅助回路(低、中、v)
elif v>分拣机[mid]:
辅助回路(中+1、高、v)
其他:
中途返回
elif高==低:
返回(如果v==分拣机,则为低[低]否则为无)
返回辅助(0,len(分拣机),v)
#添加一些测试以确保实现是正确的
如果“名称”=“\uuuuuuuu主要”:
a=[x代表范围(0,101,2)内的x]
b=[x代表范围(1100,2)内的x]
打印('a:',a)
打印('b:',b)
print('binarySearching:'、all(a中x的isinstance(binarySearching(a,x,int))和all(b中x的binarySearching(a,x)为None))
打印('otherBinarySearching:'、全部(otherBinarySearching(a,x)==x/2表示a中的x)和全部(otherBinarySearching(a,x)表示b中的x为无))

此外,您的版本返回了错误的索引:行
return mid
返回子数组二进制搜索当前正在查看的
v
的索引,而不是原始数组中的索引。

是的,这看起来是正确的,是什么让您认为它可能不正确?你在列表上测试过吗<代码>a=[x代表范围内的x(0,101,2)]b=[x代表范围内的x(1,100,2)]打印(全部(二进制搜索(a,x代表范围内的x))打印(任何(二进制搜索(a,x代表范围内的x))如果你的程序是正确的,应该先打印“真”,然后打印“假”。对不起,测试应该是:
a=[x代表范围内的x(0,101,2)]b=[x代表范围内的x(1,100,2)]print(all(二进制搜索(a,x)==x/2表示a中的x)和all(二进制搜索(a,x)表示b中的x为None))
如果程序正确,则应打印“true”。实际上,您的实现不正确。行
return mid
返回
mid
的值,它是当前正在搜索的子数组中
v
的位置,而不是原始数组中
v
的位置。除了返回错误的索引外,其余代码都是正确的;当
v
在数组中时,您可以测试它是否返回
int
;当它不在
isinstance
时,它是否返回
int
a=[x代表范围内的x(0,101,2)]b=[x代表范围内的x(1,100,2)]打印(全部(isinstance(二进制搜索(a,x,int)代表a中的x)和全部(二进制搜索(a,x)代表b中的x)是无的)