python3实现二分法查找并返回元素位置

Python递归实现二分法 题目要求: 编写函数,用二分法在有序列表中查找元素,找到则返回下标,找不到则返回-1。编写主程序,输入列表元素,调用第2题的函数排序,输入一个数,调用本题的函数查找。列表输入一次,查找可输入多次。尝试用递归实现 题目解析: 首先,要搞清楚什么是二分查找法。其次,要搞清楚什么是递归。二分查找法只对有序的数据有效。二分查找法天然地蕴含了递归的思想。了解二分法的基本思想可参考博客 代码: ''' 编写函数,用二分法在有序列表中查找元素, 找到则返回下标,找不到则返回-1。 编写主程序,输入列表元素,调用第 阅读详情

二分法作为一种比较经典的查找算法,经常在面试中被提及。网上有递归和非递归两种方式,同时还有返回元素下标和不返回两种版本,这篇文章我们就分别用递归和非递归方式来实现返回元素下标的版本。

二分法查找

先来了解下二分法的思路。

二分法的特点是查找速度快,但处理对象必须是有序列表。如下图所示,整个列表是升序排列的,要查找48所在的位置(如果该元素存在的话)。首先找到居中的元素36,发现48比36大,于是在36右边的子列表中继续查找。又找到居中元素52,发现36比52小,于是在52左边的子列表中继续查找。此时的子列表只剩下了一个元素,刚好等于48。一共迭代3次,比从头遍历的5次要少。

1-binary.png

代码实现

输入只有两个,有序列表和待查找的值,输出要么是找到的元素下标,要么是返回None表示没找到。

非迭代实现

非迭代版本的好处就是可以一直对同一个列表进行操作,所以只需要两个游标分别指向子列表的左右俩边界即可。

直接给出实现代码

def binary_search(list_: list, item):
    '''non-recursive version'''
    n = len(list_)
    left = 0
    right = n - 1
    while left <= right:
        mid = (left + right) // 2
        if list_[mid] == item:
            return mid
        elif item < list_[mid]:
            left = left
            right = mid - 1
        elif item > list_[mid]:
            left = mid + 1
            right = right
    return None

这里的left是最左边元素的下标,right是最右边元素的下标。要注意这里的边界,最左边是从0开始。通过不停对left和right赋值,从而实现在循环中不停对新的子列表进行操作。当最后两个游标重合并且所指向的元素不是要寻找的值时,此时新的left会比新的right大1,跳出循环,返回None。

下面来验证下

if __name__ == '__main__':
    list_ = [9, 11, 33, 36, 48, 52, 74, 87]
    for item in [7,9,11,33,36,37,48,52,74,87,88,100]:
        result = binary_search(list_, item)
        print(result)

返回的结果如下,符合预期

None
0
1
2
3
None
4
5
6
7
None
None

迭代实现

迭代的缺点就是不能直接对原列表进行操作,这也是为什么在《python3实现快速排序算法图文详解》中,要传递两个游标的位置作为参数的原因。不过我们这里并不需要返回完整列表,只需要返回下标即可,所以新列表也无所谓。

直接看代码。

def binary_search(list_: list, item):
    '''recursive version'''
    n = len(list_)
    if n < 1:
        return None
    left = 0
    right = n - 1
    mid = (left + right) // 2
    if list_[mid] == item:
        return mid
    elif item < list_[mid]:
        newList = list_[0:mid]
        newResult=binary_search(newList,item)
        if newResult is None:
            return None
        else:
            return binary_search(newList, item)
    elif item > list_[mid]:
        newList = list_[mid+1:]
        newResult=binary_search(newList,item)
        if newResult is None:
            return None
        else:
            return mid + binary_search(newList, item) + 1

主要逻辑就是,当中间值比查找值大的时候,直接返回子列表的查询结果。而当中间值比查找值小的时候,要注意用mid加上新的查找值还要再加1。当子列表长度为0时退出迭代。

这里要注意边界条件,左边子列表是list_[0:mid],这里的最后mid对应的值是不包括在子列表中的。

同时要注意None的处理,当最后一层迭代返回None时,再与前面的数值进行计算会报错。所以要进行额外的判断,当下一层迭代返回了None,也就是最后没找到时,本层也会返回None。

验证结果也同意没问题

None
0
1
2
3
None
4
5
6
7
None
None

时间复杂度

最好的情况是直接第一步就在中点找到,而最坏的情况是一直二分到了最后,一共二分了logn次,所以时间复杂度为O(logn)。

完整代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time: 2020-Jul-21
# @Author: xiaofu


# def binary_search(list_: list, item):
#     '''non-recursive version'''
#     n = len(list_)
#     left = 0
#     right = n - 1
#     while left <= right:
#         mid = (left + right) // 2
#         if list_[mid] == item:
#             return mid
#         elif item < list_[mid]:
#             left = left
#             right = mid - 1
#         elif item > list_[mid]:
#             left = mid + 1
#             right = right
#     return None


def binary_search(list_: list, item):
    '''recursive version'''
    n = len(list_)
    if n < 1:
        return None
    left = 0
    right = n - 1
    mid = (left + right) // 2
    if list_[mid] == item:
        return mid
    elif item < list_[mid]:
        newList = list_[0:mid]
        newResult=binary_search(newList,item)
        if newResult is None:
            return None
        else:
            return binary_search(newList, item)
    elif item > list_[mid]:
        newList = list_[mid+1:]
        newResult=binary_search(newList,item)
        if newResult is None:
            return None
        else:
            return mid + binary_search(newList, item) + 1


if __name__ == '__main__':
    list_ = [9, 11, 33, 36, 48, 52, 74, 87]
    for item in [7,9,11,33,36,37,48,52,74,87,88,100]:
        result = binary_search(list_, item)
        print(result)

我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。

Python入门之二分法查找 算法:二分法查找适用于数据量较大时,但是数据需要先排好顺序。主要思想是:(设查找的数组区间为array[low, high])(1)确定该区间的中间位置K(2)将查找的值T与array[k]比较。若相等,查找成功返回此位置;否则确定新的查找区域,继续二分查找。区域确定如下:a.array[k]>T 由数组的有序性可知array[k,k+1,……,high]>T;故新的区间为array[low,……,K-1]b.array[k] 阅读详情

相关推荐

算法第三期——二分法(Python)

二分法:把一个长度为n的有序序列上O(n)的查找时间,优化到了O(logn)。

荷叶田田的博客 10000

【Python-二分法-查找重复值】

如果被查找的有序序列存在多个相同的值a,则普通的二分法返回的结果无法确定是第几个a。 在上述常见的二分法的基础上,可以设置flag参数(如果flag=0则表示查找第一个a,如果flag=1则表示查找最后一个a),则改进的二分法的算法逻辑如下: 步骤1.判断被查找有序序列 arr[] 的中间值 arr[mid] , 其中mid=(low+high) 整除 2 ,low 和 high表示被查找序列中最小值和最大值的索引值。如果 arr[mid]等于被查找值a,则将mid值赋给tmp; 步骤2.如果上述flag被

liujingwei8610的专栏 1844

动态掩码语言模型(MLM)优化策略:效率提升与最新技术实践

本文深入探讨了动态掩码语言模型(MLM)的优化策略与技术实践,涵盖核心原理、效率优化及2025年最新突破。重点解析了动态掩码在提升模型性能中的关键作用,包括工程实现、掩码策略演进及混合专家动态掩码等创新技术,为自然语言处理领域的研究与应用提供实用指南。

vscode5coder的博客 210

python二分查找

有序数组,进行二分查找 numbers = [1,3,5,6,7,8,13,14,15,17,18,24,30,43,56] head,tail = 0,len(numbers) search = 24 while tail -head &amp;gt;1: mid = (head + tail)//2 if search == numbers[mid]: ans = m...

youyoudao 679

使用 Python 获取网络数据

本文介绍了 Python 获取网络数据、使用 requests 库、编写爬虫代码以及使用 IP 代理的方法。Python 的 requests 库非常方便,可以帮助我们快速访问网络资源。编写爬虫程序需要掌握正则表达式、HTTP 协议等知识,同时需要注意爬取速度和频率,以避免对被爬取网站造成负担。最后,使用 IP 代理可以帮助我们隐匿身份,保护我们的网络安全。

互联说 2695

Yolov26 在 Rk3588 上的 Rknn Onnx 部署实践(模型转换)

本文详细介绍了将YOLOv26 ONNX模型转换为RKNN模型的过程,适用于RK3588平台。主要内容包括:1)量化数据集的创建,通过随机抽取最多400张JPG图片生成校准数据集;2)ONNX转RKNN的完整脚本,支持多种量化方式和平台适配;3)模型转换的参考调用方式;4)模型结构对比展示。文章还提供了注意事项,强调量化数据集图片尺寸、mean/std值需与实际推理一致,并给出精度优化建议。该转换流程为YOLOv26模型在RK3588上的高效部署提供了完整解决方案。

qq_64366203的博客 1125

使用Python实现二分查找算法及其应用场景详解

二分查找算法最常见的应用场景就是在有序数组中查找特定元素。例如,在一个存储学生分数的数组中,我们可以使用二分查找快速定位某个分数是否存在,或者找到分数所在的位置。例如,在搜索某个函数的零点时,我们可以使用二分查找算法确定一个区间,并在该区间上进行迭代,逐步逼近零点。综上所述,二分查找算法具有较低的时间复杂度,适用于静态有序数据集的查找问题。在旋转有序数组中查找目标元素 下面是一个示例,演示如何在旋转有序数组中使用二分查找算法来查找目标元素。作为输入,并返回目标元素在数组中的索引。

这里是RabbitTuzi哦~ 9229

NXP KW47蓝牙MCU低功耗实测:从8μA睡眠到5年续航的优化实战

在物联网和嵌入式系统开发中,低功耗设计是决定电池供电设备续航能力的关键技术。其核心原理在于通过事件驱动、状态机管理和精细的电源域控制,使设备在空闲时进入深度睡眠,仅在需要时快速唤醒工作,从而将平均电流从毫安级降至微安级。这项技术的工程价值在于能够实现纽扣电池供电设备长达数年的使用寿命,广泛应用于智能家居传感器、可穿戴设备、资产追踪和工业监测等领域。以NXP KW47系列无线MCU为例,其集成的Arm Cortex-M33双核与专用射频单元,配合多级睡眠模式和高效DC-DC转换器,为超低功耗蓝牙应用提供了硬件

weixin_30162121的博客 255

python之二分查找

思路: 1. 先给定一个范围 比如:1-100 2. 先找这个范围的一半mid,也就是数字50(下标为49) 3. 如果找大了,则将最大范围设为 mid-1,此时范围为数字1-49(下标范围:0-48) 4. 如果找小了,则将最小范围设为 mid+1,此时范围为数字50-100(下标范围:51-100) 5. 重复2-4步骤,直到找到这个数字...

m0_56945138的博客 854

用Zotero+B站Kimi,我如何把一篇顶会论文快速做成组会PPT(含完整提示词)

本文介绍如何利用Zotero和Kimi快速将顶会论文转化为组会PPT,提升学术汇报效率。通过Zotero的文献管理插件和Kimi的AI提炼技术,实现从论文阅读到PPT生成的全流程自动化,帮助研究者在90分钟内完成高质量汇报准备。

weixin_30955617的博客 499

vue2/3 - 详细实现内网使用离线高德地图功能,在vue中无需网络离线使用高德地图相关功能,高德地图如何离线加载详细教程(内网部署及使用),提供最新完整的瓦片资源下载及相关工具(示例代码,一键复制

vue,vue2,vue3,高德地图,离线使用高德地图,高德地图瓦片官方下载,vue内网使用高德地图离线无网络,断网情况下使用高德地图,vue离线高德地图教程,如何实现内网部署高德地图,无需联网离线使用,vue+ts实现离线高德地图 内网离线高德地图,如何在高德地图Vue项目中下载离线地图,高德离线地图加载不出来,高德地图离线使用不显示怎么办,怎么解决vue内网使用离线高德地图加载失败问题,vue实现离线地图+高德瓦片,vue引入高德离线地图,vue项目如何使用离线高德地图和自定义地图样式,高德离线地图的下

✅ 精选推荐文章 1万+

【数据结构与算法】python实现二分查找

python实现二分查找

weixin_43911004的博客 1万+

ROS机器人未知环境自主探索功能包explore_lite最全源码详细解析(一)

本系列文章主要针对ROS机器人常使用的未知环境自主探索功能包explore_lite展开全源码的详细解析,并进行概括总结。 本系列文章共包含六篇文章,前五篇文章主要介绍explore_lite功能包中 explore.cpp、costmap_tools.h、frontier_search.cpp、costmap_client.cpp等源码实现文件中全部函数的详细介绍,第六篇文章进行概括总结,包含自主探索功能包explore_lite的简介,实现未知环境自主探索功能的原理及流程总结,效果演示,使用功能包

慕羽★的博客 3935

查找算法/搜索 | 二分法(python)

Hi,大家好,我是半亩花海。近期在学习算法与数据结构相关知识,纯纯小白,欢迎一起交流呀。打算从算法学起,首先学习搜索算法中的二分法,我使用的是 python 语言进行学习,本算法学习参考了很多博主的文章。

沉思默想,深度学习,半亩星河半亩月,半亩花海半亩云。 1万+

使用 Prometheus 监控 Spring Boot 应用

本文介绍了使用SpringBoot+Prometheus+Grafana实现应用监控的方案。首先在SpringBoot项目中集成Micrometer和Actuator组件,通过配置暴露Prometheus监控端点。接着配置Prometheus采集应用指标数据,并通过Grafana可视化展示。具体步骤包括:1)SpringBoot集成Micrometer;2)配置Prometheus抓取应用指标;3)安装Grafana并导入SpringBoot监控模板;4)展示JVM和业务指标。该方案可以实现对SpringB

蔡定努 430

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

python实现二分法查找_python3 二分法查找

'''二分法查找有序列表掐头去尾取中间查找列表中xx在不在列表中,在,则返回索引值'''# lst = [1, 4, 6, 8, 9, 21, 23, 26, 35, 48, 49, 54, 67, 89, 99] #使用in判断,不使用二分法# n = 49# for i, v in enumerate(lst):# if v == n:# print("找到了,索引为%...

weixin_39917046的博客 779

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

用Python实现二分法查找

运用python语言实现二分法查找的一个小例子,掌握二分法的思想。

weixin_62517099的博客 1万+

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Python算法题集_在排序数组中查找元素的第一个和最后一个位置

题目34. 在排序数组中查找元素的第一个和最后一个位置;给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target,返回 [-1, -1]。你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。

长孤秋落的札记 1265

Day1-python实现二分法查找以及移除元素

二分法查找是一种高效的查找算法,适用于在有序数组中查找特定元素。其基本思想是通过逐步缩小查找范围,快速定位目标值的位置。

重做解斑的博客 1623

python 二分法查找(递归实现和循环实现)

1.什么是二分法查找? “二分法”查找的场景可以想象做一群小孩上体育课的时候按高矮个排队,按个子从矮到高顺序排好了之后, 小孩A姗姗来迟,这时候老师就说,“来,报个数,你们班排在中间的同学M举下手”,然后小孩A和小孩M比身高,要是小孩A比M高,那小孩A的位置上肯定要安排在M之后,否则就安排在M之前。就这样缩小范围后,在重复上面的操作,直到小孩A找到了个他同样高的小孩B,这就是小孩A的位置了。当然,小孩A要是站进队里,那就是“插入”操作了。 当然,这样讲并不是下定义,而是理解一下这个场景。 2.二分法查找的前

小太阳xss的博客 1307

二分法查找原理步骤及python快速实现

二分法原理,步骤解析,以及python快速实现!!!

木子偉 2244

python用二分法查找元素_Python二分法查找及变种分析

基于Python3普通二分法查找目标值的index二分法查找的思路很简单,先确定好列表nums的一头start一尾end,中间值middle根据头尾数值之和用地板除法除以2,即(start + end) // 2。将目标值target与nums[middle]进行比对,这时候有3种结果:nums[middle] > targetnums[middle] < targetnums[middle] =...

weixin_39630762的博客 499

浅谈二分查找 以Python为语言实现(一)

在基本算法中,二分法无疑是最常用且高效的技术之一。它广泛应用于求解各种问题,特别是在确定性的单调场景中。本节将详细介绍二分法的理论背景、模板代码以及典型题目,并简要提及与之相关的三分法。

2301_80323116的博客 1457

LeetCode 二分法查找 (Python3)

LeetCode Q33-Q35Q33 搜索旋转排序数组 Search in Rotated Sorted ArrayQ34 在排序数组中查找元素的第一个和最后一个位置 Find First And Last Position of Element in Sorted ArrayQ35 搜索插入位置Q33 - Q35 一些笔记 Q33 搜索旋转排序数组 Search in Rotated Sorted Array 升序排列的整数数组 nums 在预先未知的某个点上进行了旋转(例如, [0,1,2,4,5,

SandWHaleXYl的博客 320

python二分法排序_二分法排序-Python实现

有一个无序序列[37,99,73,48,47,40,40,25,99,51],先进行排序打印输出,分别尝试插入20/40/41 数值到序列中合适的位置,保证其有序。1、for 循环实现第一种实现,利用嵌套for循环,每次迭代出来的数值进行比较。如果比原表中的数值小,则插入到这个数左面。lst1 = [37,99,73,48,47,40,40,25,99,51]lst = sorted(lst1)f...

weixin_39656435的博客 1506

python实现二分法查找

python 实现 二分法 查找

范枝洲的博客 2219
上一篇: Linux中free命令各字段详解以及内存和cache相关知识整理
下一篇: python3实现二叉树图文详解
T型人小付
博客等级 码龄7年 433粉丝 210原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值