python实现素数筛选法_二分查找法的Python实现-1(极其高效的查找算法)

1. 二分查找法,顾名思义每次将待查找的列表范围折半,直到找到待查找元素,或者发现待查找元素不在当前的列表中。

2. 二分查找法的适用场景必须是应用在有序的列表中,才能表现出比顺序查找更好的性能。

3. 有序列表的元素值的递增方向可以是从小到大排列,也可以是从大到小排列。

4. 更优的算法是,待查找的范围是整个列表的子表(缩小查询范围),但索引必须连续,其实此种优化对二分查找法的效率提升并不明显,但是对于某种情况下顺序查询的性能提升还是巨大的。

5、 对于需要频繁进行增、删、改操作的列表(进而可以引申到对数据库中某个数据源的操作),实时排序会大大影响程序的整体性能,因此二分查找法适用于数据源相对静态(增删改操作对数据排序影响不大)、对并发查询性能要求高(注意每种算法都有其局限性)。

举例讲解:

ff97356e47d4c892419e68f427c75045.png

将列表的12个元素比作12个蓝色的桶

上面依次排列有12个蓝色的桶,每个桶内放了一个数字卡片,且卡片数字递增。假设我们并不知道每个桶内卡片上的数字,需要每次取出卡片进行比较才能得到结果。那么如果想要知道卡片77在哪个桶内,需要怎么进行查找呢?

注释:列表的索引为每个桶的标号(下方红色字体),列表的索引值从0开始的,因此桶的标识也是从0开始。

继续回答上面的问题,我们可能首先想到的是顺序查找,这种算法逻辑处理简单,就是从第一个0号桶中开始,依次取出每个桶中的卡片与待查找的数据进行比较,直至找到数字是77的卡片 ,并得到桶号(列表索引值)是9。此种方法一共要经历10次循环的比较运算才能得到结果(这是在列表中存在带查找数据的情况下,否则情况会更糟)。 那么如果应用二分查找法会怎么样呢,这里先给出答案,二分查找法需要经历的循环比较次数为4次(log12)。

继续提问,上面的例子中,是以有12个元素的列表为例,那么如果列表包含1200个数据元素,顺其推理,顺序查找所需的时间应该是对于具有12个元素列表查找的100倍;并且很顺理成章的认为,二分查找法所需的时间也是对12个元素的列表查询的100倍。事实是这样么?答案是否定的。我们运用大O表示法O(n)和O(logn) 来分别表示这2种查询算法所需运算时间,O(n)所需的时间是线性增加的,但是O(logn)显然不是,它是对数时间,其时间增加值是离散量。在大O表示法中,n表示列表具有的元素数量,O(n)和O(logn)分别表示顺序查找法与二分查找法的最大运行次数(相对时间)。

4e5ea97698b72e89e1ead71aa4109791.png

如果是这个量级,该如何应对

如上图所示,联想到全国有14亿人(神联想),如果是待查询的元素是这个量级,那么二分查找法的最大循环运行次数为31次,假设每次循环执行时间为1ms计算,最多需要31ms可得到查询结果;如果是顺序查找呢,需要的时间超过16天(是不是心里落差有点大)。二分查找法的运行时间实际上是以2为底数n的对数,对数运算与幂运算互为逆运算,这里31的由来也就是log14亿(0.38)向上取整得出。

继续以上述的具有12个元素的列表进行详细的分析,我们定义变量left和right为待查询列表的左右边界索引,初始值left = 0,right = 0;定义 变量mid为每次待查询范围的中间元素索引值 ,mid = (left + right)// 2(向下取整)。

1dcb3cbe4198e8d971550b64a25a1916.png
fc5fd143f1f509b4e150281f47db2284.png
10797ed657343e830430fdd2dcfb2e52.png
52bd9b7f8ffce878a398feab96ba4e4a.png

此节主要讲述了二分查找法的实现原理、优点及适用场景,并与顺序查找法进行了比较,突显出其对于有序列表进行查询的巨大性能优势。下节主要在视频中,讲述二分查找法的Python代码实现,以代码方式模拟对于不同数据量的列表(100、1000或1亿元素)查找时,以更加直观的方式突显出二分查找法的性能优势。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值