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)是无的)