一. while循环二分
二分查找.每次能排除掉一半的数据.查找的效率非常高.但是局限性比较大,必须是有序的序列才能用二分查找.
要求:
要查找的序列必须是有序序列.
#二分法查找某一个数的索引位置
lst = [11,22,33,44,55,66,77,88,99,111,122,133,144,155,166,177,188,199]
n = 122
left = 0
right = len(lst) - 1 # 以索引为边界
while left<=right:
middle = (left + right) // 2 # 取一个在中间位置的索引
if n >lst[middle]: #如果要查找的数大于列表中索引在中间的元素
left = middle +1 #重新定义边界,将左边界向右边挪一位
elif n < lst[middle]: #如果查找的数小于中间值
right = middle -1 #重新定义边界,将右边界向左边挪一位
else: #如果查找的数等于中间值,直接打印middle
print('在索引为'+ str(middle) +'的位置上!')
break
else:
print('不存在')
#结果:
#在索引为10的位置上!
二. 函数递归二分法
lst = [11, 22, 33, 44, 55, 66, 77, 88, 99, 111, 122, 133, 144, 155, 166, 177, 188, 199]
def f(left,right ,n): #定义一个函数,给三个形参
middle = (left+right)//2
if n >lst[middle]:
left = middle +1
elif n<lst[middle]:
right = middle - 1
else:
return middle
return f(left,right,n) #必须要加return,要不然会返回none,因为它只会返回给调用它的函数
i = f(0,len(lst)-1,99)
print(i)
#结果:
#8
三. 函数递归第二种方法(只能查找在不在序列内,不能查找具体位置)
lst = [11, 22, 33, 44, 55, 66, 77, 88, 99, 111, 122, 133, 144, 155, 166, 177, 188, 199]
def f(lst,n): #因为这个方法会改变列表,所以要将列表作为参数
left = 0
right = len(lst) - 1
middle = (left+right)//2
if middle<0:
print('没找到')
return
if n >lst[middle]:
lst = lst[middle+1:] #对列表切割
elif n<lst[middle]:
lst = lst[:middle-1]
else:
print('找到了')
return
f(lst,n) #递归再次调用函数
f(lst, 76)
#结果:
#没找到