昨天晚上参加面试,python实现二分查找:当时满脑子都是for循环
以下纯属个人理解
先讲一下什么是二分查找:二分查找顾名思义就是要对半查找,从整个数组中找中间的一个做判断。那么要求数组是有序的。
【所以,千万别做傻事 去for循环】此情可待成追忆,只是当时很傻呵。
python实现的方式有2种,一是非递归版本,二是递归版本
# 非递归版本
def fun_binary_search(ts,t):
""" t:目标元素,
ts: 表示寻找范围的数组
return : 返回下标
"""
height= len(ts) -1 # 因为是返回下标,所以要减一,不然会始终多1
low = 0
while low <= height: #某些情况下 他们相等也要做判断
mid = (low + height) // 2
if ts[mid] == t:
return mid
elif ts[mid] > t: # 说明我们找的范围大了,要去小的范围找
height = mid - 1
else:
low = mid + 1
return None
ts = [1,2,4,5,6,7]
print(fun_binary_search(ts,4)) # 2
# 递归版本,基础版本,只能返回是否存在不能返回下标,因为通过切片破坏了ts
def fun2_binary_search(ts, t):
"""
递归的方法就是要 改变ts的范围实现查找
t:目标元素
ts:表示寻找范围的数组
return : 返回Teur 或者 False
"""
low = 0
height = len(ts) - 1
mid = (low + height) // 2
if ts[mid] == t:
return True
elif ts[mid] > t:
return fun2_binary_search(ts[:mid], t)
else:
return fun2_binary_search(ts[mid + 1:],t)
ts = [1,2,4,5,6,7]
print(fun2_binary_search(ts,4)) # True
# 这种递归方式,过于繁琐,需要一直维持下标,不美观
def fun3_binary_search(ts,t,low,height):
'''
:param ts: 数组
:param t: 目标值
:param low: 下标最小值
:param height: 下标最大值
:return:
'''
if height == 0:
return False
else:
if low <=height:
mid = (low+height) //2
if ts[mid] == t:
return mid
elif ts[mid] > t:
return fun3_binary_search(ts,t,low,height=mid-1)
else:
return fun3_binary_search(ts,t,low=mid+1,height=height)
ts = [1,2,4,5,6,7]
# 传参不同 注意
print(fun3_binary_search(ts,4,0,len(ts)-1)) # 2
# 这种递归将维持的下标通过内嵌的方式传参
def fun4_binary_search(ts,t):
'''
使用内嵌的方式,将传参隐藏
:param ts: 数组
:param t:目标值
:return: 下标
'''
def inner_func(low,height):
if low <= height:
mid = (low + height) // 2
if ts[mid] == t:
return mid
elif ts[mid] < t: # 寻找的元素小了,那要把最小值提高
return inner_func(low=mid+1,height = height)
else:
return inner_func(low=low,height=mid-1)
return False
return inner_func(0,len(ts)-1)
ts = [1,2,4,5,6,7]
print(fun4_binary_search(ts,4))