前提:在一个有序无重复元素的数组 nums 中,寻找一个元素key,如果找到了就返回对应的下标,如果没找到就输出提示:未找到。
示例:
使用二分法必须要满足的条件:
1、数组是有序数组,如果是乱序数组,二分法无法有效查找
2、数组中元素不能有重复,有重复的话二分法返回的下标可能是不唯一的
用一个猜数字的例子来深入理解一下这两个条件:
我从[1,2,3,4,5,6,7,8,9,10]中选一个数字,小爱同学来猜我选的是几,我会告诉他猜大了还是小了
游戏开始,我选择了8
小爱同学没有任何思路,于是决定一个一个试
小爱同学:是1吗?
我:小了
小爱同学一个一个问,每个问题只能让它排除一个数字
小爱同学:是2吗?
我:小了
小爱同学:是3吗?
我:小了
小爱同学:是4吗?
我:小了
小爱同学:是5吗?
我:小了
小爱同学:是6吗?
我:小了
小爱同学:是7吗?
我:小了
小爱同学:是8吗?
我:对了!
这种查找方式也适用于计算机,遍历数组,一个一个找,总能找到或者确定查找项不在数组里,但是当数字数量很多,目标数又很靠后时,就要浪费一定的时间和资源量了。于是乎。。
小爱同学升级了一下思路:
小爱同学:是5吗?
我:小了
小爱同学问了一个比较靠中间的数字,这一个问题让他排除掉了 1,2,3,4,5
小爱同学:是8吗?
我:对了!
小爱同学把范围锁定在[6,7,8,9,10],又取了一个靠中间的数字,很幸运就是8!
即使这一次没有猜对,也同样可以排除掉 6,7,8 或者 8,9,10 三个选项,进一步锁定答案
这就是二分法的思想,在有序且不重复的数组中,每一次都能在备选项里面排除一半的错误答案。程序实现思路基本一致:
python实现:
#二分法
def fun(list1,key,left,right):
if list1[left] <= key <= list1[right]:
mid = (left + right) // 2
if list1[mid] == key:
return mid
elif list1[mid] < key:
return fun(list1,key,mid+1,right)
else:
return fun(list1,key,left,mid-1)
else:print("未找到")
print("单调递增整数组:")
li = [int(a) for a in input().split()]
print("list=",li)
print("你要找谁:")
key = int(input())
end = len(li)-1
print("是:list[",fun(li,key,0,end),"]")