循环实现二分查找通过维护左右边界迭代缩小范围,初始化left=0、right=count($arr)-1,mid=(left+right)/2,相等返回mid,大于target则right=mid-1,小于则left=mid+1。

一、使用循环实现二分查找
循环实现方式通过维护左右边界索引,在每次迭代中比较中间元素与目标值,逐步缩小搜索范围,避免函数调用开销,适合对空间复杂度敏感的场景。
1、定义一个接受已排序数组和目标值的函数,初始化左边界 $left = 0,右边界 $right = count($arr) - 1。
2、当 $left
3、若 $arr[$mid] 等于目标值,立即返回 $mid。
4、若 $arr[$mid] 大于目标值,将 $right 更新为 $mid - 1。
5、若 $arr[$mid] 小于目标值,将 $left 更新为 $mid + 1。
6、循环结束后未找到,返回 -1 表示查找失败。
二、使用递归实现二分查找
递归实现将问题分解为子问题,每次调用处理当前搜索区间的子数组,逻辑清晰,符合二分查找的自然分治思想,但需注意 PHP 默认递归深度限制。
1、定义递归函数 binarySearchRecursive($arr, $target, $left, $right),初始调用传入 $left = 0 和 $right = count($arr) - 1。
2、在函数内判断 $left > $right,若成立则直接返回 -1。
3、计算 $mid = (int)(($left + $right) / 2),并比较 $arr[$mid] 与 $target。
4、若相等,返回 $mid。
5、若 $arr[$mid] > $target,递归调用自身,参数为 $left 和 $mid - 1。
6、若 $arr[$mid] 递归调用自身,参数为 $mid + 1 和 $right。
三、封装为可复用的静态工具方法
将二分查找封装为类中的静态方法,支持泛型式调用,增强代码复用性与类型一致性,适用于项目中多处需查找的场景。
1、创建名为 BinarySearch 的类,内部定义 public static function search($arr, $target)。
2、在方法内先校验 $arr 是否为数组且非空,若不满足则返回 -1。
3、校验数组是否已升序排列,可通过遍历相邻元素判断,若发现降序则抛出异常或返回错误码。
4、采用循环方式执行核心查找逻辑,确保边界安全与整数除法兼容性。
5、查找到时返回索引,否则返回 -1。
四、处理重复元素时定位最左/最右位置
标准二分查找仅返回任意一个匹配索引;当数组含重复值且需精确控制返回位置时,需扩展逻辑以锁定边界索引。
1、实现最左查找:当 $arr[$mid] == $target 时,不立即返回,而是继续向左收缩右边界 $right = $mid - 1。
2、循环结束后,检查 $left 是否越界或 $arr[$left] 是否等于 $target,若否,返回 -1;若是,返回 $left。
3、实现最右查找:当 $arr[$mid] == $target 时,不立即返回,而是继续向右收缩左边界 $left = $mid + 1。
4、循环结束后,检查 $right 是否越界或 $arr[$right] 是否等于 $target,若否,返回 -1;若是,返回 $right。
五、使用 SPL 的 ArrayObject 配合自定义比较器
借助 SPL 提供的可迭代结构,结合用户定义的比较逻辑,使二分查找适配对象数组或复杂数据结构,提升灵活性。
1、将数据封装为 ArrayObject 实例,并确保其按关键字升序排列。
2、编写比较函数 compare($a, $b),返回 -1、0 或 1,用于判定大小关系。
3、在查找过程中,所有大小判断均调用该函数,而非直接使用 。
4、中间值获取仍基于索引,但比较操作统一委托给 compare 函数,确保语义一致性。
5、查找到后返回原始数组中的键名或索引,保持与原始数据结构映射关系。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











