Python算法入门——第3章 3.1 二分法

本文深入浅出地介绍了二分查找算法,通过日常生活中的实例,如查找字典和猜数字游戏,阐述了二分查找的基本原理。文章详细解释了算法的实现过程,包括如何通过不断缩小查找范围来提高效率,并提供了Python代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二分法查找是一种十分高效的方法,可以在极少的步数之内查找到我们需要的内容。这种方法在我们日常生活中随处可见,你可能在熟练地运用这种方法,但是你却没有意识到他的存在罢了。我们先讲几个简单的例子,来说明一下什么是二分法:

小学时,人手一本新华字典。当你去查找  “馄饨”  的读音时,你可能会先去目录找到  h 的对应页数,在进行查找,但当你熟练运用字典之后,你可能直接翻到  h 所在的那一部分进行查找了,因为你知道 h 是在中间部分,根本不需要去看前一部分或者后一部分。

我们以前也玩过一种猜数字游戏,一个人说出一个数字,知道答案的人会告诉你,这个数是大了还是小了,然后你不断的调整自己猜的数字,直到猜中正确答案。如果给定的区间是 0 - 100,正确数字是99,而你从1开始往上猜,那么你最多要猜99次;然而使用了二分查找之后你只需要猜测中间数进行比较,不断缩小剩余区间,在经过极少的步骤之后,你就会得到正确的答案。利用二分法查找最多需要\large \log_2{n}步。这会极大地缩减时间

这都是二分法在现实生活中的例子,二分查找的基本思想是将n个元素分成大致相等的两部分,取a[n/2]与x做比较,如果x=a[n/2],则找到x,算法中止;如果x<a[n/2],则只要在数组a的左半部分继续搜索x,如果x>a[n/2],则只要在数组a的右半部搜索x.。那么接下来,我们就用Python代码来实现二分查找。话不多说,上代码:

def Solution(list,item):
    '''
    二分法,用来在有序列表里面查找索引
    :param list:输入的有序列表
    :param item:你需要查找的元素
    :return:返回的是查找元素在列表里面的下标
    '''
    #用来记录尾部数据的位置坐标
    high = len(list) - 1
    #用来记录头部数据的位置坐标
    low = 0
    #当中间数值的个数不为1时,循环缩小判断区间
    while low <= high:
        #mid为中间数值的下标
        mid = int((low + high)/2)
        #guess为中间数值
        guess = list[mid]
        #如果中间数值正好为我们要查找的数值,直接返回
        if guess == item:
            return mid
        #如果我们要查找的数值小于中间数值
        elif guess > item:
            #那么就把high置位
            high = mid - 1
        #如果我们要查找的数值大于中间数值
        else:
            #那么就把low置位
            low = mid + 1

#主程序
if __name__ == '__main__':
    a = [1,2,3,4,5,6,7,8,9]
    b = 3
    print(Solution(a,b))

注意:我们给定的list列表必须是有序的,否则我们就不可能在有限的步骤之内查找到我们需要的内容 

代码分析:

1.首先我们利用哨兵  high  来记录数据尾部的数据位置,利用哨兵 low 记录数据头部分的数据位置,区间 [low, high] 就是存在正确答案的区间。

2.写入一个  while 循环,只要我们的区间 [low , high ] 的数据个数大于1 就继续循环主体程序来缩小区间的大小,直到剩下一个数字,这个数字就是正确答案。这有点类似于高等数学里面的 “夹逼定理” 不断缩小正确答案的空间,直到找到正确答案

    2.1计算中间数值 mid的大小(要转换为 int 变量)利用中间值将区间分为大于中间值的一部分跟小于中间值的一部分,通过判断中间值跟正确答案的大小关系来不断缩小猜测区间。

    2.2如果猜测的数值等于正确答案,那么直接返回正确答案的下标值

    2.3如果猜测的数值大于正确答案,那么说明正确答案存在于两个区间中较小的那个区间,这样就保持 哨兵low不动,哨兵high 变为 mid - 1。

    2.4如果猜测的数值小于正确答案,那么说明正确答案存在于两个区间中较大的那个区间,这样就保持 哨兵high不动,哨兵low变为 mid + 1。

    2.5 就通过这样不断循环,直至逼近正确答案。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值