二分查找,《学点算法吧,Python》

本文介绍了二分查找,一种适用于有序序列的高效查找方法。相比顺序查找的O(n)时间复杂度,二分查找的时间复杂度为O(log n),但要求数据已排序。文章通过Python代码展示了二分查找的实现,并指出其对数据存储顺序的严格要求。

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

二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,二分查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。


顺序查找、简单查找

介绍二分查找之前,我们先看一下最容易理解的顺序查找或者说简单查找

顺序查找也就是傻找,一个一个对比,直到成功匹配查找值。最坏的情况在最后一个元素才匹配到查找值。

  • 顺序查找的运行时间是O(n)。
  • 顺序查找虽然‘傻’,但是它对数据存储顺序没有要求,是最通用的查找算法。

Python实现如下

生成无序列表


def ord_list(n): #生成有序列表
    ord = list(range(n))
    return ord

def ran_list(n): #生成无序列表
    ran = ord_list(n)
    random.shuffle(ran)
    return ran

简单查找算法

def simple_search(key,list): #实现简单查找
    num=0                      #记录操作次数
    for index,i in enumerate(list):
        num+=1
        if key==i:
            print('元素{}在列表中的索引为{}'.format(key,index))
            print('共查找{}次'.format(num))
            return index

输出结果

if __name__=='__main__':
    n=10000
    key=random.randint(0,n-1) #生成查找值
    ran = ran_list(n) #生成无序列表,10000个参数
    print('从列表中查找元素{}'.format(key))
    simple_search(key,ran)



'''
输出结果如下:

从列表中查找元素1288
[7167, 4864, 4521, 6352, 2578, 6109, 7097, 
3186, 2952, 7662, 2372, 8252, 3776, 8912,
 ...... 
8038, 5548, 2742, 216, 8100, 104, 691, 7095,
 5141, 7030, 9587, 644, 9676, 8165, 481]
元素1288在列表中的索引为7315
共查找7316次

'''

二分查找

当序列为有序时,再使用简单查找那就真的‘傻’了。

二分查找

  1. 首先要满足顺序序列的前提,以升序为例
  2. 查找值序列中间值进行比对
  3. 如匹配成功则返回中间值索引
  4. 当查找值大于中间值舍弃前面一半序列,反之舍弃后面一半序列
  5. 循环进行直到匹配成功,或仅有一个元素仍不满足匹配,则序列中无查找元素

最多需要log n步。

  • 二分查找的运行时间时O(log n)
  • 二分查找的前提,序列必须是有序

Python实现如下

二分查找算法

def binary_search(key,list):
    num = 0  # 查找次数
    low = 0  # 最小数下标
    high = len(list) - 1  # 最大数下标
    while low <= high:
        num+=1
        mid = (low + high) //2  # 中间数下标
        if list[mid] == key:  # 如果中间数下标等于key, 返回
            print('元素{}在列表中的索引为{}'.format(key, mid))
            print('共查找{}次'.format(num))
            return mid
        elif list[mid] > key:  # 如果key在中间数左边, 移动high下标
            high = mid - 1
        else:  # 如果val在中间数右边, 移动low下标
            low = mid + 1
    print('该列表中不存在元素{}'.format(key))
    return  # key不存在, 返回None

输出结果

if __name__=='__main__':
    n=10000
    key=random.randint(0,n-1)
    ord = ord_list(n)
    print('从列表中查找元素{}'.format(key))
    print(ord)
    binary_search(key,ord)
'''
输出结果如下:
从列表中查找元素2560
[0, 1, 2, 3, 4, 5, 
......
 9996, 9997, 9998, 9999]
元素2560在列表中的索引为2560
共查找13次

'''

从10000个元素中查找一个随机数,仅仅需要13步,效率还是相当可观的。


总结

  • 二分查找比简单查找快得多
  • 二分朝朝要求必须是有序序列
  • 简单查找对序列几乎没有要求
  • O(log n)比O(n)快。需要搜索的元素越多,前者比后者就快的越多

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值