二分查找列表中的数据

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

如果要被查找的数列 是有序的(例如从小到大递增排列的数列 ,在索引值为0的位置是整个数列 中最小 的数字,而数列 中最后一个数字是数列中最大的数字),那么还有一个更快的查找方法,即二分查找法。它每次都取数列 的中间值来检查,如果 找到的数字比目标值小,下一次就到队列的右边去找,否则就往队列的左边去找,每次都会缩小范围,一直到找到或是找不到为止。

提示:以下是本篇文章正文内容,下面案例可供参考7-1
以图7-1的数列为例,总共有15个数字,假设索引值是1-15(不过请注意python列表的索引值是从0开始的)。在此设置了用来指定要查找的最小范围(对应索引变量min)、最大范围(对应索引变量max)以及目标索引值(对应变量target)。开始的时候,min=1,max=15,而target的计算公式为:
target= floor((min+max)/2)
其中floor是批无条件会去小数的取整数函数,也就是整队的意思。根据上述公式,target的计算结果为8.
算出了目标target之后,就按该目标所指向的索引去检查这个位置上的数字是大于我们要查找的数字还是小于我们要找的数字,如果大于,就把范围缩小到列表的左边,反之缩小到列表的右边。
以上面的列表数据为例,如果要找的数字是28,在第8个位置的数字是39,它比28大,因此就要把max指向targetg-1,也就是索引值7,反之把min指向target+1,如图7-2所示。
7-2
接着重新计算target,得到的是4,如图7-3所示
7-3
此是再比较位置4的内容和28之间的关系,如果不相等,再重新设置范围,直到找到或找不到为止,接下来的步骤分别如图7-4和7-5所示。

如果指定的数字还是找不到的,假如在上面的例子中我们要找的是29,那么在图7-5中因为29比28大,因此要把min设置为target+1 ,也就是6,此时出现的情况就是代表最小查找范围索引值变量min的值是6,代表最大范围索引值变量max的值是5, max <min是不合理的情况,表示程序不用要再继续查找了,要找的数值根本不在数列中。
以这种每次都排除二分之一查找对象的方式,就可以保证在有序的数列 中,能以最少的查找次数找到目标值或是确定找不到目标值,假设数列中有n个数字,则二分查找法的平均查找次数为log2n.
由于min和max这两个单词均为Python的函数名称,为了避免冲突,因此 在具体实现时我们将其分别改为left和right,代表要查找范围的左边界和右边界。此外,target为计算出来要对比的索引值,lst[target]则是要进行对比的元素值,至于用户输入要那寻找的数字则存放在变量n中。
图7-6为二分查找法的流程图。
7-6

lst= [7, 12, 16, 23, 28, 32, 34, 39, 45, 54, 59, 68, 73, 79, 88]
n = int(input("请输入你要找的数字:"))
left ,right = 0, len(lst) -1
target = (left + right) // 2
while lst[target] != n and left <= right:
    if n > lst[target]:
        left = target + 1
    else:
        right = target - 1
    target = (left + right) // 2
    print("n:{}, lst[target]:{}, left:{}, right:{}, target:{}".format(n, lst[target], left, right,target))
if left > right:
    print("你要找的数字{}并不在数列中!".format(n))
else:
    print("你要找的数字{},在数列第{}个位置上".format(n,target))
    请输入你要找的数字:100
n:100, lst[target]:68, left:8, right:14, target:11
n:100, lst[target]:79, left:12, right:14, target:13
n:100, lst[target]:88, left:14, right:14, target:14
n:100, lst[target]:88, left:15, right:14, target:14
你要找的数字100并不在数列中!
请输入你要找的数字:88
n:88, lst[target]:68, left:8, right:14, target:11
n:88, lst[target]:79, left:12, right:14, target:13
n:88, lst[target]:88, left:14, right:14, target:14
你要找的数字88,在数列第14个位置上
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值