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

Java 二分查找实现(附完整思路)

前提说明

二分查找(折半查找)只能作用于有序数组! 核心思想:不断缩小查找区间,每次用中间元素和目标值对比,排除一半区间,时间复杂度 \(O(logn)\);顺序查找是 \(O(n)\)。

算法思路

  1. 定义左右边界:left = 0(数组起始下标),right = arr.length - 1(数组末尾下标)
  2. 循环条件:left <= right,区间内还有元素可以比较
  3. 计算中间下标mid推荐写法mid = left + (right - left) / 2,防止(left+right)数值溢出
  4. 三种情况判断:
    • arr[mid] == target:找到目标,返回 mid 索引
    • arr[mid] < target:目标在右半区,更新左边界left = mid + 1
    • arr[mid] > target:目标在左半区,更新右边界right = mid - 1
  5. 循环结束仍未找到,返回 -1(代表不存在)

⚠️ 注意边界:mid+1/mid-1,不要重复比较 mid 位置元素,否则容易死循环。

方式 1:迭代实现(日常开发最常用)

java

运行

public class BinarySearch { /** * 二分查找 迭代版 * @param arr 有序升序数组 * @param target 要查找的值 * @return 找到返回下标,找不到返回 -1 */ public static int binarySearch(int[] arr, int target) { // 1. 初始化左右指针 int left = 0; int right = arr.length - 1; // 2. [left, right] 闭区间,left <= right 区间有效 while (left <= right) { // 计算中间索引,避免 left+right 溢出 int mid = left + (right - left) / 2; if (arr[mid] == target) { // 3. 找到目标,直接返回下标 return mid; } else if (arr[mid] < target) { // 目标在右侧,左边界右移,mid已经比较过,+1 left = mid + 1; } else { // 目标在左侧,右边界左移 right = mid - 1; } } // 循环结束没有找到 return -1; } public static void main(String[] args) { int[] sortedArr = {1, 3, 5, 7, 9, 11, 13}; int target1 = 7; int target2 = 4; int index1 = binarySearch(sortedArr, target1); int index2 = binarySearch(sortedArr, target2); System.out.println(target1 + " 下标:" + index1); System.out.println(target2 + " 下标:" + index2); } }

方式 2:递归实现(适合理解思想,工程慎用,大数据量会栈溢出)

java

运行

public class BinarySearchRecursion { public static int binarySearch(int[] arr, int left, int right, int target) { // 递归终止条件:区间不存在 if (left > right) { return -1; } int mid = left + (right - left) / 2; if (arr[mid] == target) { return mid; } else if (arr[mid] < target) { // 去右区间递归查找 return binarySearch(arr, mid + 1, right, target); } else { // 去左区间递归查找 return binarySearch(arr, left, mid - 1, target); } } public static void main(String[] args) { int[] arr = {2, 4, 6, 8, 10, 12}; int res = binarySearch(arr, 0, arr.length - 1, 8); System.out.println("索引 = " + res); } }

常见易错点总结

  1. 数组必须有序,无序数组不能直接二分查找;
  2. mid = (left + right) / 2当 left、right 很大时会整数溢出,优先left + (right-left)/2
  3. 区间定义:本例是闭区间 [left, right],所以循环条件left <= right,边界更新mid±1; 如果写成左闭右开[left, right),循环条件和边界赋值写法需要改动;
  4. 如果数组存在重复元素,该代码只会返回任意一个匹配下标,不能保证第一个 / 最后一个; 想要查找左边界、右边界,需要改造逻辑。

扩展:JDK 自带二分方法

Arrays.binarySearch()

java

运行

import java.util.Arrays; public class Test { public static void main(String[] args) { int[] arr = {1,2,3,4,5}; int idx = Arrays.binarySearch(arr, 3); System.out.println(idx); } }

找不到时不会返回 - 1,返回-(插入点)-1,使用时需要留意判断逻辑。

http://www.jsqmd.com/news/1247879/

相关文章:

  • 本体语义AI:让机器真正“读懂“业务的钥匙
  • 亲身探访绍兴亨得利名表服务中心|全新地址及售后电话(2026年7月更新) - 亨得利官方
  • 2026 推荐舟山非急救长途转运|正规救护车跨省护送服务 - 官方推广
  • 嵌入式Flash性能优化:预取缓冲与镜像模式实战解析
  • Flutter第十七节-----路由管理(3)
  • 幼儿园工作总结模板:PDCA循环与数据可视化实践
  • 032、YOLOv8改进实战:TripletAttention三重注意力机制原理与C2f_Triplet模块代码实现
  • Python毕设项目:基于 Python 的数字化音乐资源管理与播放平台 个性化音乐收藏与播放记录系统 (源码+文档,讲解、调试运行,定制等)
  • AI社交平台如何提升工作与学习效率
  • 卡萨帝冰箱CASARTE推出全国统一24小时售后服务电话人工上线2026最新公布 - 优企名品
  • AIGC助手如何提升内容创作效率与质量
  • 安阳文峰区新房除甲醛怎么选?多家深度对比测评,靠谱除醛门店首选安阳森家环保 - 专注室内空气检测治理
  • WT7015三功能手电筒芯片WT7015
  • 独立站供应链协同与订单履约效率研究——基于BBWEYY一体化后台的考察,含零代码SAAS、AI编程、源码定制交付
  • AI智能体的核心能力与工程实现详解
  • 深入解析MSPM0 RTC寄存器:从原理到实战,解决嵌入式时钟开发难题
  • AI大模型就业市场分析与技能指南
  • 想给爸妈补补身体,哪种奶源可追溯的羊奶粉靠谱一点 - 资讯在线
  • 深度学习模型压缩:稀疏计算与结构化剪枝实践
  • 形态学实战:基于形态学的图像噪声去除优化
  • 万国手表回收2026吉林市须知|毓典寄卖行本地实体回收门店 - 毓典寄卖行
  • 2026江苏公考备战,选对“封闭式基地班“到底有多重要?
  • 摄像头频繁重启、关键录像凭空消失?一份企业监控运维排障 + 改造全流程手册!
  • 技术解析|Google Gemini 3.6 正式发布!推理、代码、多模态全方位技术升级
  • 欧米茄服务项目及价格查询|全新地址及售后热线权威信息公告(2026年7月最新) - 欧米茄官方服务中心
  • 033、YOLOv8改进实战:GAM全局注意力机制原理与C2f_GAM模块代码实现
  • 探秘外贸专业的谷歌自然排名服务商,究竟有何独特之处?
  • 亨得利售后维修怎么样?专业保养服务与客户口碑解析权威公示(2026年7月最新) - 亨得利官方
  • 太好了!千问App给新用户发8元红包啦!下载后只要输入 千问新人福利uqo6UY 即可领取8元通用立减券,简单又好用,快来领取吧!
  • NLP文本预处理核心技术解析与实践指南