查找算法之二分查找原理及实现

290 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第21天,点击查看活动详情

1.算法知识点

二分查找是一种算法,其输入是一个有序的元素列表(必须有序的原因稍后解释)。如果要查找的元素包含在列表中,二分查找返回其位置;否则返回null。 我们了解一下二分查找的工作原理,随便想一个1~100的数字,我们的目标是以最少的次数猜到这个数字,如果我们一次一次的向上验证,这就是简单查找,更准确的说是傻找,每次猜测都只能排除一个数字,最差情况下这个数字如果是100,那我们就得猜100次.

2.更佳的查找方式

我们可以从中间开始猜,不管怎么样,我们排除了一半的数字,然后再猜大的部分的中间数字。这就是二分查找,使用二分查找,每次都排除一半的数字。不管想的是哪个数字,在7次之内都能猜到,因为每次猜测都会排除很多数字。 假设我要在字典中查找一个单词,而该字典包含240000个单词。如果查找的单词位于字典末尾,使用简单查找需要240000步。使用二分查找时,每次排除一半,直至最后一个单词。那么就需要18步。因此用二分查找最多需要logn步,而简单查找最多需要n步。

仅当列表是有序的时候,二分查找才管用。例如,电话簿中的名字是按字母顺序排列的,因此可以使用二分查找来查找名字。

3.算法思路

在一个数组中,每次都检查中间的元素,如果猜的数字小了,就相应的修改low,如果猜的数字大了,就修改high。最后返回数字所在的位置。

4.算法题解

image.png

my_list=[1,2,5,7,9,11,35,46,67,112,324]#定义一个数组
def binary_search(list,item):
    low=0
    high=len(list)-1#设置上下界
    while low<=high:  #只要两者之间还有空隙就需要继续进行查找
        mid=int((low+high)/2)#就检查中间的元素
        guess=list[mid]
        if guess==item:#找到数字的情况
            return mid
        if guess>item:#猜的数字大了
            high=mid-1
        else:       #猜的数字小了
            low=mid+1
    return None
binary_search(my_list,11)

5.时间复杂度比较和总结

我们现在分析一下运行时间。一般而言,应选择效率最高的算法,以最大限度地减少运行时间或占用空间。回到前面的二分查找。使用它可节省多少时间呢?简单查找逐个地检查数字,如果列表包含100个数字,最多需要猜100次。如果列表包含40亿个数字,最多需要猜40亿次。换言之,最多需要猜测的次数与列表长度相同,这被称为线性时间( linear time)。二分查找则不同。如果列表包含100个元素,最多要猜7次;如果列表包含40亿个数字,最多需猜32次。厉害吧?二分查找的运行时间为对数时间(或log时间)。