导读:本期聚焦于小伙伴创作的《二分查找是什么?二分查找的边界条件有哪些需要注意的》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《二分查找是什么?二分查找的边界条件有哪些需要注意的》有用,将其分享出去将是对创作者最好的鼓励。

二分查找是一种针对有序数据集合的高效查找算法,核心思路是通过不断将查找区间对半分割,缩小目标元素的存在范围,直到找到目标或者确认目标不存在。它的时间复杂度为O(log n),相比线性查找的O(n)效率提升非常明显,因此被广泛应用于各类查找场景中。

二分查找是什么?二分查找的边界条件有哪些需要注意的

二分查找的基本原理

二分查找的前提是待查找的数组必须是有序的,可以是升序也可以是降序,本文后续示例默认以升序数组为例。查找过程分为以下几个步骤:

  • 初始化两个指针,左指针指向数组起始位置,右指针指向数组结束位置
  • 计算中间位置mid,对比mid位置的元素和目标值的大小
  • 如果mid位置元素等于目标值,直接返回mid索引
  • 如果mid位置元素小于目标值,说明目标值在mid右侧,将左指针移动到mid+1的位置
  • 如果mid位置元素大于目标值,说明目标值在mid左侧,将右指针移动到mid-1的位置
  • 重复上述过程,直到左指针超过右指针,说明目标值不存在,返回-1

二分查找的基础实现示例

以下是升序数组二分查找的基础代码实现,以Python语言为例:

def binary_search(arr, target):
    left = 0
    right = 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  # 未找到目标值

# 测试示例
test_arr = [1, 3, 5, 7, 9, 11, 13]
print(binary_search(test_arr, 7))  # 输出3
print(binary_search(test_arr, 8))  # 输出-1

二分查找的核心边界条件

二分查找的边界条件处理是容易出现错误的地方,不同的边界定义对应不同的代码逻辑,下面介绍几个最常见的边界条件相关的问题。

1. 右指针的初始化方式

右指针的初始化有两种常见方式,不同的初始化会影响后续的循环条件和指针移动逻辑:

右指针初始化循环条件指针移动规则适用场景
right = len(arr) - 1left <= rightleft = mid + 1, right = mid - 1查找目标值的精确索引,区间闭区间[left, right]
right = len(arr)left < rightleft = mid + 1, right = mid查找第一个大于等于目标值的位置,区间左闭右开[left, right)

如果右指针初始化为len(arr),表示查找区间是左闭右开的,此时循环条件需要改为left < right,因为右指针指向的位置本身不在查找范围内,当left等于right时,区间已经为空,不需要继续循环。对应的代码示例如下:

def binary_search_left_open(arr, target):
    left = 0
    right = len(arr)  # 右指针初始化为数组长度,指向的位置不在查找区间内
    while left < right:  # 循环终止条件:左指针等于右指针,区间为空
        mid = (left + right) // 2
        if arr[mid] < target:
            left = mid + 1
        else:
            right = mid  # 目标值可能在mid位置,右指针移动到mid
    return left  # 返回第一个大于等于target的位置

test_arr = [1, 3, 5, 7, 9, 11, 13]
print(binary_search_left_open(test_arr, 7))  # 输出3
print(binary_search_left_open(test_arr, 8))  # 输出4,即第一个大于8的元素9的位置

2. 循环终止条件

循环终止条件需要和右指针的初始化方式匹配,常见的错误是混用两种边界定义的逻辑,比如右指针初始化为len(arr)-1却使用left < right作为循环条件,这会导致当目标值刚好在最后一个元素时无法被查找到。

当使用闭区间[left, right]时,循环条件必须是left <= right,因为当left等于right时,区间仍然包含一个元素,需要继续判断;当使用左闭右开区间[left, right)时,循环条件必须是left < right,因为left等于right时区间已经没有元素了。

3. mid的计算方式

计算mid时如果使用(left + right) // 2,在left和right都很大的时候可能会出现整数溢出的问题,不过在Python中整数没有大小限制,这个问题不常见,但在Java、C++等语言中需要注意,可以使用left + (right - left) // 2的方式计算mid,避免溢出。

另外,在查找第一个等于目标值或者最后一个等于目标值的位置时,mid的计算可能需要向上取整,避免死循环。比如查找第一个大于等于目标值的位置时,如果mid计算向下取整,当区间只剩两个元素且left指向的元素小于target,right指向的元素大于等于target时,mid会一直等于left,导致left永远无法更新,进入死循环。此时可以将mid的计算改为(left + right + 1) // 2,向上取整。

4. 指针移动的规则

指针移动的规则也需要和区间定义匹配,闭区间场景下,当arr[mid]不等于target时,target肯定不在mid位置,因此left可以移动到mid+1,right可以移动到mid-1;而左闭右开区间场景下,当arr[mid]大于等于target时,target可能在mid位置,因此right只能移动到mid,不能移动到mid-1,否则会漏掉mid位置的元素。

常见边界错误案例

以下是一个典型的边界错误示例,右指针初始化为len(arr)-1,却使用了左闭右开的指针移动逻辑:

def wrong_binary_search(arr, target):
    left = 0
    right = 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  # 错误:闭区间下right应该移动到mid-1
    return -1

test_arr = [1, 3, 5, 7, 9]
print(wrong_binary_search(test_arr, 9))  # 会进入死循环

上述代码中,当查找目标值为9时,left=0,right=4,mid=2,arr[2]=5<9,left变为3;此时mid=(3+4)//2=3,arr[3]=7<9,left变为4;此时mid=(4+4)//2=4,arr[4]=9等于target,返回4,看似没有问题,但如果目标值不存在,比如查找10,left=4,right=4,mid=4,arr[4]=9<10,left变为5,此时left>right,循环结束返回-1,这个场景下不会出错,但如果数组是[1,3,5,7,9,10],查找10,也会出现类似的问题吗?其实这个例子的错误更典型的是当arr[mid]大于target时,right移动到mid,会导致当区间只剩两个元素时,right永远无法小于left,比如数组[1,2],查找0,left=0,right=1,mid=0,arr[0]=1>0,right变为0,此时left=0,right=0,mid=0,arr[0]还是大于0,right又变为0,进入死循环。

总结

二分查找的边界条件处理核心是保持区间定义的一致性,无论是选择闭区间还是左闭右开区间,后续的循环条件、指针移动规则都要和初始的区间定义匹配,不能随意混用。在编写二分查找代码时,可以先明确自己的区间定义,再按照对应的逻辑编写代码,这样可以有效避免大部分边界错误。如果遇到复杂的二分查找场景,比如查找第一个等于目标值的位置、查找最后一个等于目标值的位置,也可以先明确区间定义,再调整对应的逻辑,确保代码的正确性。

二分查找binary_search算法边界条件修改时间:2026-07-11 09:54:36

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。