当前位置: 首页 > news >正文

【每日一算法】二分查找

在图书馆,需要查找一本书。首先想到如何快速找到它?

书籍通常按顺序排列(字母顺序或字母数字顺序),这就是二分查找适用的场景。你可以快速排除一半的书籍,每次比较后再缩小范围,迅速定位目标书籍。这比逐页查找要高效得多。
二分查找是一种算法,其输入是一个有序的元素列表(必须有序二分查找(Binary Search),也称折半查找,是一种在有序数组中查找特定元素的高效算法。它可以快速找到目标值的索引(如果存在),否则返回null。

二分查找使用条件

  • 数组必须是有序(通常是升序或降序)。
  • 数据类型必须允许比较(如数字、字符串等)。

二分查找的工作原理

  1. 初始化两个指针:low(初始为数组首元素索引)和 high(初始为数组末尾元素索引)。

  2. low <= high 的情况下循环执行以下步骤:

    • 计算中间索引 midmid = (low + high) // 2

    • 将目标值与数组中位于 mid 的元素进行比较:

      • 如果目标值等于数组的中间元素,返回 mid(找到目标)。

      • 如果目标值小于中间元素,说明目标位于左半部分,更新 high = mid - 1

      • 如果目标值大于中间元素,说明目标位于右半部分,更新 low = mid + 1

  3. 如果循环结束仍未找到目标值,返回 -1(表示未找到)。

代码示例

def binary_search(arr, target):
    low = 0
    high = len(arr) - 1

    while low <= high:
        mid = (low + high) // 2  # 计算中间索引
        if arr[mid] == target:
            return mid  # 找到目标
        elif arr[mid] < target:
            low = mid + 1  # 目标可能位于右半部分
        else:
            high = mid - 1  # 目标可能位于左半部分
    return -1  # 未找到目标

# 测试
my_list = [1, 3, 5, 7, 9]
target = 3
result = binary_search(my_list, target)
if result != -1:
    print(f"元素 {target} 在数组中的索引是 {result}")
else:
    print(f"未找到元素 {target}")

算法分析

时间复杂度为 O(log n) ,这是由于每次都将查找范围减少一半,因此非常适合大规模数据的快速查找。

应用场景

以下是一些实际应用场景:
1. 人员管理中的员工信息查找
在企业员工管理系统中,可以根据员工编号(有序)快速查找员工信息。
# 假设员工信息存储为按员工号升序排列的列表
employees = [
    {"id": 100, "name": "Alice", "position": "Manager"},
    {"id": 200, "name": "Bob", "position": "Engineer"},
    {"id": 300, "name": "Charlie", "position": "HR"}
]

# 查找员工号为 200 的员工信息
def find_employee_by_id(id_list, target_id):
    return binary_search(id_list, target_id)

# 员工号列表(有序)
id_list = [100, 200, 300]
target_id = 200
index = find_employee_by_id(id_list, target_id)
if index != -1:
    employee = employees[index]
    print(f"找到员工:{employee['name']},职位:{employee['position']}")
else:
    print("未找到该员工")
2. 从库存数据库中查找产品
在库存管理系统中,产品按编号或名称字母顺序存储,二分查找可用于快速定位特定产品。

注意事项

  • 数据必须有序:否则二分法无法正确工作。如果输入是无序的,需要先排序。
  • 边界条件处理:
    • 如果数组为空,函数应该返回 None 或 -1。
    • 如果数组长度为 1 或 2,要确保逻辑正确。

总结

二分法通过分治思想,将问题规模不断缩小,从而快速定位目标元素。时间复杂度为 O(log n),非常高效,是处理有序数据时的强大工具。

相关文章:

  • 学习经验分享【39】YOLOv12——2025 年 2 月 19 日发布的以注意力为核心的实时目标检测器
  • vue2 和 vue3 中 computer 计算属性的用法
  • 单臂路由
  • 【算法系列】荷兰国旗问题:三指针法原地排序
  • comfy 面部修复(ComfyUI-Impact-Pack)
  • mybatis 细节(${ ..}和#{..},resultType 和 resultMap的区别,别名的使用,Mapper 代理模式)
  • vue-treeselect显示unknown的问题及解决
  • React 高阶组件的优缺点
  • CMake入门
  • HDFS Java 客户端 API
  • QML MouseArea 鼠标事件详解
  • SQLMesh 系列教程8- 详解 seed 模型
  • 每日一题——验证IP地址
  • Docker教程(喂饭级!)
  • 数字化电子(不动产经营租赁服务)发票版式文件说明
  • 孜然单授权系统V2.0PHP授权系统
  • List 接口中的 sort 和 forEach 方法
  • Linux-GlusterFS进阶分布式卷
  • python 虚拟机的使用方式
  • 实验-安装Proteus
  • 告别户口本!今天起婚姻登记实现全国通办
  • 重温经典|《南郭先生》:不模仿别人,不重复自己
  • 洞天寻隐·学林纪丨玉洞桃源:仇英青绿山水画中的洞天与身体
  • 毗邻三市人均GDP全部超过20万元,苏锡常是怎样做到的?
  • 波音公司计划于2027年交付新版“空军一号”飞机
  • 牛市早报|央行宣布降准降息,公募基金改革最新方案落地