Python中如何实现二分查找?

python中实现二分查找的步骤包括:1. 基本实现,使用标准的二分查找算法;2. 优化版本,避免整数溢出;3. 查找第一个匹配索引,处理重复元素;4. 处理唯一元素的优化;5. 自定义比较函数的实现。通过这些步骤,二分查找可以高效地应用于各种场景,提升编程能力。

Python中如何实现二分查找?

在Python中实现二分查找是一种高效的搜索算法,特别适用于有序数组。让我们深入探讨如何实现这个算法,并分享一些我在这方面的经验和见解。

二分查找的核心思想是通过不断将搜索范围缩小一半来快速找到目标元素。假设我们有一个有序的列表,我们可以从中间开始,如果目标值大于中间值,我们就在右半部分继续查找;如果小于中间值,我们就在左半部分继续查找。这种方法的平均时间复杂度是O(log n),这使得它在处理大规模数据时非常高效。

让我们来看一个具体的实现:

立即学习“Python免费学习笔记(深入)”;

def binary_search(arr, target):    left, right = 0, len(arr) - 1    while left <= right:        mid = (left + right) // 2        if arr[mid] == target:            return mid        elif arr[mid] < target:            left = mid + 1        else:            right = mid - 1    return -1  # 如果没有找到目标值,返回-1

这个实现非常简洁,但我们可以进一步优化和扩展它。首先,我们可以使用left + (right - left) // 2来计算中间值,这样可以避免在处理非常大的数组时可能出现的整数溢出问题:

def binary_search_optimized(arr, target):    left, right = 0, len(arr) - 1    while left <= right:        mid = left + (right - left) // 2        if arr[mid] == target:            return mid        elif arr[mid] < target:            left = mid + 1        else:            right = mid - 1    return -1

在实际应用中,我发现二分查找的一个常见误区是处理边界条件。特别是当数组中存在重复元素时,如何返回第一个或最后一个匹配的索引是一个挑战。让我们看一个返回第一个匹配索引的实现:

def binary_search_first_occurrence(arr, target):    left, right = 0, len(arr) - 1    result = -1    while left <= right:        mid = left + (right - left) // 2        if arr[mid] == target:            result = mid            right = mid - 1  # 继续在左半部分查找        elif arr[mid] < target:            left = mid + 1        else:            right = mid - 1    return result

这个实现会继续在左半部分查找,直到找到最左边的匹配元素。类似的,我们可以实现一个查找最后一个匹配索引的版本。

在性能优化方面,二分查找已经非常高效,但我们可以考虑一些特殊情况。例如,如果我们知道数组中的元素是唯一的,我们可以提前终止搜索:

def binary_search_unique(arr, target):    left, right = 0, len(arr) - 1    while left <= right:        mid = left + (right - left) // 2        if arr[mid] == target:            return mid        elif arr[mid] < target:            left = mid + 1        else:            right = mid - 1    return -1

在实际应用中,我发现二分查找的一个常见问题是处理非标准的比较函数。例如,如果我们需要在自定义对象中进行二分查找,我们可以传递一个比较函数:

def binary_search_custom(arr, target, compare_func):    left, right = 0, len(arr) - 1    while left <= right:        mid = left + (right - left) // 2        cmp = compare_func(arr[mid], target)        if cmp == 0:            return mid        elif cmp < 0:            left = mid + 1        else:            right = mid - 1    return -1# 示例用法class Person:    def __init__(self, name, age):        self.name = name        self.age = agedef compare_person(person, target_age):    return person.age - target_agepeople = [Person("Alice", 25), Person("Bob", 30), Person("Charlie", 35)]result = binary_search_custom(people, 30, compare_person)if result != -1:    print(f"找到年龄为30岁的人:{people[result].name}")else:    print("未找到")

通过这些例子,我们可以看到二分查找的灵活性和广泛应用。无论是处理基本数据类型还是自定义对象,二分查找都能提供高效的解决方案。

在实际项目中,我建议在使用二分查找时,首先确保数组是有序的,并且考虑到边界条件和特殊情况。同时,根据具体需求选择合适的变体(如查找第一个或最后一个匹配的元素),可以大大提高代码的实用性和鲁棒性。

总之,二分查找是一种强大且高效的算法,掌握它的实现和优化技巧可以显著提升你的编程能力。

以上就是Python中如何实现二分查找?的详细内容,更多请关注php中文网其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1360746.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
为什么ESP32深度睡眠唤醒后显示rst:0x5 (DEEPSLEEP_RESET)和boot:0x13 (SPI_FAST_FLASH_BOOT)?如何解决这个问题?
上一篇 2025年12月13日 23:56:07
Python中如何实现快速排序?
下一篇 2025年12月13日 23:56:13

相关推荐

  • java中new的作用 对象实例化的底层机制解析

    new关键字用于分配内存并初始化对象。1)jvm在堆中分配内存,设置对象头信息。2)调用构造方法完成初始化。3)使用对象池和延迟初始化可优化性能。 在Java中,new关键字是一个非常基础却又强大的工具,用于创建对象实例。那么,new的作用究竟是什么?对象实例化的底层机制又是如何运作的?让我们深入探…

    2026年8月25日
    000
  • 如何在Symfony应用中高效发送短信通知?使用symfony/twilio-notifier让集成变得轻而易举

    可以通过一下地址学习composer:学习地址 “叮咚!” 想象一下,你的电商平台用户成功下单后,能即时收到一条短信通知:“您的订单#12345已成功提交,预计三天内送达。” 或者,当用户忘记密码时,通过短信接收验证码来重置密码。这些场景在日常应用中司空见惯,而其背后都离不开一个关键的服务:短信通知…

    用户投稿 2026年8月25日
    000
  • linux下怎么安装php

    linux下安装php的方法:1、下载php源码;2、解压安装包;3、配置安装变量;4、编译源码;5、切换到root用户,执行【make install】命令安装php。 环境: linux系统 php5.6 具体步骤如下: 立即学习“PHP免费学习笔记(深入)”; (推荐教程:linux视频教程)…

    2026年8月25日
    000
  • Java中JDBC的作用是什么 详解JDBC规范统一数据库操作的优势

    Java中JDBC的作用是什么 详解JDBC规范统一数据库操作的优势Java中JDBC的作用是什么 详解JDBC规范统一数据库操作的优势Java中JDBC的作用是什么 详解JDBC规范统一数据库操作的优势Java中JDBC的作用是什么 详解JDBC规范统一数据库操作的优势

    jdbc通过提供标准api简化数据库操作。1. 加载数据库驱动,2. 建立数据库连接,3. 执行sql语句,4. 处理结果集。使用preparedstatement可有效防止sql注入攻击,同时对用户输入进行验证、过滤及采用最小权限原则进一步保障安全性。 JDBC(Java Database Con…

    2026年8月25日 用户投稿
    000
  • 如何解决大型PHP项目数据传输混乱问题,使用Spryker/Transfer构建标准化数据对象

    Composer在线学习地址:学习地址 大型PHP项目的数据传输之痛:混乱与低效 在php的世界里,尤其是在中大型项目中,我们经常需要将数据从一个地方传递到另一个地方:从控制器到服务层,从服务层到仓库层,再从仓库层返回数据。最常见的做法是什么?没错,就是使用关联数组(associative arra…

    用户投稿 2026年8月25日
    000
  • 悟空浏览器官方网页入口 悟空浏览器最新官网主页

    悟空浏览器官方网页入口是https://www.wukong.com,用户可通过该网址访问官网,使用智能搜索、跨设备同步及内容聚合等服务。 悟空浏览器官方网页入口在哪里?这是不少网友都关注的,接下来由PHP小编为大家带来悟空浏览器最新官网主页,感兴趣的网友一起随小编来瞧瞧吧! https://www…

    2026年8月25日
    000
  • 无主之地4支线最最最后召唤图文攻略 支线最最最后召唤怎么做

    无主之地4支线最最最后召唤图文攻略 支线最最最后召唤怎么做无主之地4支线最最最后召唤图文攻略 支线最最最后召唤怎么做无主之地4支线最最最后召唤图文攻略 支线最最最后召唤怎么做无主之地4支线最最最后召唤图文攻略 支线最最最后召唤怎么做

    《无主之地4》支线任务“最最最后召唤”图文指南:如何完成“暴民正义”前置并解锁任务 任务开启条件 想要接取“最最最后召唤”这一隐藏支线,必须先完成“暴民正义”任务的前置要求。 前往“老大酒馆”,进入大厅后在吧台附近找到特定NPC进行对话,即可触发任务接取流程。 任务执行步骤 跟随系统指引前进,你会发…

    2026年8月25日 用户投稿
    000
  • 进程守护(Daemon)与自动重启

    设计健壮的守护进程和实现自动重启机制的方法如下:1. 守护进程设计:使用python和相关库(如psutil和daemon)创建守护进程,监控cpu使用率并记录日志。2. 自动重启机制:使用supervisor配置文件,设置进程自动启动和重启,并记录错误和输出日志。通过资源管理、日志记录、错误处理和…

    2026年8月25日
    000
  • Redis集成难题?Spryker/Redis如何解决模块解耦问题

    在构建大型电商平台时,我们经常需要用到 Redis 这种高性能的键值存储系统。然而,在 Spryker 这样的模块化框架中,直接使用 Redis PHP 客户端可能会导致模块间的耦合度增加,维护起来比较麻烦。Spryker/Redis 模块就是为了解决这个问题而生的,它提供了一个统一的 Redis …

    用户投稿 2026年8月25日
    000
  • Java中jstack的用法 详解线程转储

    Java中jstack的用法 详解线程转储Java中jstack的用法 详解线程转储Java中jstack的用法 详解线程转储Java中jstack的用法 详解线程转储

    jstack是用于诊断java应用线程问题的关键工具,它通过生成线程转储帮助分析死锁、cpu占用高及线程等待等问题。1. 使用jps获取java进程pid;2. 执行jstack pid生成线程转储文件;3. 分析转储中的线程状态与堆栈信息,查找死锁或性能瓶颈。线程状态如blocked、waitin…

    2026年8月25日 用户投稿
    000
  • 动态内省Java类中的Jackson @JsonNaming 策略

    本文探讨了在Java中进行泛型数据反序列化时,如何动态地获取类上通过@JsonNaming注解设置的PropertyNamingStrategy。通过利用Jackson的SerializationConfig、BeanDescription和JacksonAnnotationIntrospector…

    2026年8月25日
    000
  • 告别文件类型识别难题:adrienrn/php-mimetyper助你轻松搞定MIME类型

    最近在开发一个文件上传和下载相关的模块时,我遇到了文件类型识别的问题。我需要根据文件的扩展名来判断其 MIME 类型,以便正确地处理这些文件。然而,我发现 PHP 内置的函数或者一些简单的库并不能提供足够准确和全面的 MIME 类型映射。一些文件类型的识别不够准确,而且缺少对一些常见文件类型的支持。…

    用户投稿 2026年8月25日
    300
  • Java中HashMap的工作原理是什么 图解Java HashMap的存储结构和哈希机制

    Java中HashMap的工作原理是什么 图解Java HashMap的存储结构和哈希机制Java中HashMap的工作原理是什么 图解Java HashMap的存储结构和哈希机制Java中HashMap的工作原理是什么 图解Java HashMap的存储结构和哈希机制Java中HashMap的工作原理是什么 图解Java HashMap的存储结构和哈希机制

    java hashmap通过哈希表实现键值对的高效存储与检索,其底层结构为数组加链表(或红黑树),1. 哈希函数将键转换为数组索引以定位存储位置;2. 使用链地址法解决哈希冲突,jdk 1.8后引入红黑树优化长链表查找效率;3. put操作包括计算哈希、定位桶、处理冲突及扩容判断;4. get操作通…

    2026年8月25日 用户投稿
    600
  • linux下如何关闭php服务

    linux下关闭php服务的方法:执行【kill -INT `cat /usr/local/php/var/run/php-fpm .pid`】命令即可关闭php服务。 Linux:PHP 5.3.3 以上版本的php-fpm的重启 (推荐学习教程:java课程) INT, TERM:立刻终止 QU…

    2026年8月25日
    000
  • 告别Emoji烦恼:p3k/emoji-detector如何助力PHP应用精准识别表情符号

    Composer在线学习地址:学习地址 在开发社交应用或者内容管理系统时,经常会遇到需要处理 emoji 表情符号的场景。例如,需要统计用户发送的 emoji 数量,或者需要将 emoji 替换为文本描述,亦或是需要过滤掉 emoji 以符合某些内容规范。手动编写代码来处理这些需求往往非常繁琐,而且…

    用户投稿 2026年8月25日
    000
  • kimichat官网入口地址推荐-kimichat官方网站网址导航

    Kimi智能助手官网为https://kimi.moonshot.cn/,由北京月之暗面科技有限公司推出,支持20万汉字上下文输入,具备联网搜索、文件解析、多语言翻译、代码编写、内容创作及角色扮演等功能,适用于学术研究、内容创作、金融分析、法律工作等场景,提供高效智能服务。 ☞☞☞AI 智能聊天, …

    2026年8月25日
    000
  • Java中对象流怎么使用 掌握Java序列化对象的读写方法

    Java中对象流怎么使用 掌握Java序列化对象的读写方法Java中对象流怎么使用 掌握Java序列化对象的读写方法Java中对象流怎么使用 掌握Java序列化对象的读写方法Java中对象流怎么使用 掌握Java序列化对象的读写方法

    java对象流用于序列化和反序列化,即将对象转换为字节流以实现存储或传输。1. 要实现序列化,类需实现serializable接口并建议显式声明serialversionuid;2. 使用objectoutputstream将对象写入输出流完成序列化;3. 使用objectinputstream从输…

    2026年8月25日 用户投稿
    000
  • linux下php扩展怎么正确安装

    linux下php扩展的正确安装方法:1、下载并解压扩展文件;2、进入解压文件目录,检查系统配置;3、执行【make && make install】命令安装扩展即可。 方法一:编译安装 (学习视频推荐:linux视频教程) 具体步骤: //下载文件#wget http://pecl…

    2026年8月25日
    000
  • 告别臃肿的web.php:如何使用spatie/laravel-route-attributes优雅管理Laravel路由

    可以通过一下地址学习composer:学习地址 还记得你第一次打开一个大型 laravel 项目的 web.php 文件时的感受吗?密密麻麻的 route::get(…) 、 route::post(…) ,各种中间件、前缀、命名空间交织在一起,就像一盘理不清的意大利面条。随着项目规模的扩大…

    用户投稿 2026年8月25日
    000
  • Java中Semaphore和Exchanger的应用场景解析

    Java中Semaphore和Exchanger的应用场景解析Java中Semaphore和Exchanger的应用场景解析Java中Semaphore和Exchanger的应用场景解析Java中Semaphore和Exchanger的应用场景解析

    semaphore和exchanger在java并发编程中各司其职。1. semaphore用于控制对共享资源的访问数量,适用于资源池限制、有界队列等场景;2. exchanger用于两个线程之间的数据交换,适用于生产者-消费者模型中直接交换数据的场景。semaphore通过acquire()和re…

    2026年8月25日 用户投稿
    000

发表回复

登录后才能评论
关注微信