Java—二分查找

介绍

二分查找(Binary Search)是一种在有序数组中查找特定元素的搜索算法。其基本思想是将目标值与数组中间的元素进行比较:

  1. 如果目标值等于中间元素,则查找成功。
  2. 如果目标值小于中间元素,则在数组左半部分继续进行二分查找。
  3. 如果目标值大于中间元素,则在数组右半部分继续进行二分查找。

这个过程将不断重复,直到找到目标值或搜索范围为空为止。

实现步骤

下面是二分查找算法的一般步骤:

  1. 初始化两个指针,一个指向数组的起始位置(low),另一个指向数组的结束位置(high)。
  2. 计算中间位置(mid):mid=⌊(low+high)/2⌋mid=⌊(low+high)/2⌋
  3. 比较中间元素与目标值:
    • 如果中间元素等于目标值,返回中间位置。
    • 如果中间元素大于目标值,将high更新为mid - 1。
    • 如果中间元素小于目标值,将low更新为mid + 1。
  4. 重复步骤2和3,直到找到目标值或low大于high为止。

如果最终low大于high,表示目标值不在数组中,可以返回一个表示未找到的值,比如-1。

二分查找的时间复杂度是O(log n),其中n是数组的大小。这使得它在处理大型数据集时非常高效。然而,二分查找要求数组必须是有序的,这是它的一个限制条件。

代码实现

public class BinarySearch {public static void main(String[] args) {// 初始化一个有序数组int[] arr = {1, 8, 10, 34, 44, 46, 56, 59, 61, 63, 66, 68, 69, 70, 89, 1000, 1234};// 使用递归版本查找目标值89在数组中的索引int index = binarySearch(arr, 0, arr.length - 1, 89);// 使用循环版本查找目标值89在数组中的索引int index1 = binarySearch(arr, 89);// 打印两个版本的查找结果System.out.println(index + " " + index1);}// 递归版本的二分查找算法private static int binarySearch(int[] arr, int left, int right, int target) {// 基本情况:如果left大于right,说明target不在数组中,返回-1if(left > right) {return -1;}// 计算中间索引int mid = (left + right) / 2;// 如果中间元素等于目标值,返回中间索引if(arr[mid] == target) {return mid;} else if(arr[mid] > target) {// 如果中间元素大于目标值,在左半部分递归调用二分查找return binarySearch(arr, left, mid - 1, target);} else {// 如果中间元素小于目标值,在右半部分递归调用二分查找return binarySearch(arr, mid + 1, right, target);}}// 循环版本的二分查找算法private static int binarySearch(int[] arr, int target) {// 初始化左右指针int left = 0;int right = arr.length - 1;// 当left小于等于right时,继续循环while(left <= right) {// 计算中间索引int mid = (left + right) / 2;// 如果中间元素等于目标值,返回中间索引if(arr[mid] == target) {return mid;} else if(arr[mid] > target) {// 如果中间元素大于目标值,更新right为mid-1right = mid - 1;} else {// 如果中间元素小于目标值,更新left为mid+1left = mid + 1;}}// 如果没有找到目标值,返回-1return -1;}
}

测试结果

产生问题

在二分查找算法中,计算中间索引 mid 的表达式 int mid = (left + right) / 2; 可能会在某些情况下导致问题。具体来说,如果 leftright 是非常大的整数,那么它们的和可能会超出 int 类型所能表示的范围,导致整数溢出。

整数溢出会导致 mid 的值不正确,这可能会使二分查找算法无法正确执行,甚至进入无限循环。

举例说明

解决问题

使用位运算: 使用位运算来避免溢出,因为位运算是按位进行的,不会导致溢出。计算 mid 的表达式如下: 

mid=left + (( right − left )  >> 1 )

这里,>> 是右移位运算符,它将 right - left 的二进制表示向右移动一位,相当于除以2。

使用这些方法可以确保在执行二分查找时 mid 的值是正确的,从而避免因整数溢出导致的问题

修改代码

 // 递归版本private static int binarySearch(int[] arr, int left, int right, int target) {if(left > right) {return -1;}// int mid = (left + right)/2;int mid = left + ((right - left) >> 1);if(arr[mid] == target) {return mid;} else if(arr[mid] > target) {return binarySearch(arr, left, mid - 1, target);} else {return binarySearch(arr, mid + 1, right, target);}}// 循环版本private static int binarySearch(int[] arr, int target) {int left = 0;int right = arr.length - 1;while(left <= right) {//int mid = (left + right)/2;int mid = left + ((right - left) >> 1);if(arr[mid] == target) {return mid;} else if(arr[mid] > target) {right = mid - 1;} else {left = mid + 1;}}return -1;}

测试结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/843168.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

点赋科技:闪耀荆州科技活动周,引领创新未来

在荆州 2024 科技活动周的舞台上&#xff0c;点赋科技以其卓越的科技实力和创新精神&#xff0c;成为了众人瞩目的焦点。 点赋科技&#xff0c;作为一家引领科技潮流的企业&#xff0c;一直致力于推动科技创新的发展。此次参加荆州科技活动周&#xff0c;更是展示了其在科技领域…

网络——多区域OSPF配置(OSPF系列第1篇)

简介 路由协议OSPF全称为Open Shortest Path First&#xff0c;也就开放是的最短路径优先协议&#xff0c;使用链路状态路由算法&#xff0c;isis协议也是使用链路状态路由算法。而RIP协议使用距离矢量路由算法。 区域 为了能够降低OSPF计算的复杂程度&#xff0c;OSPF采用分…

【NumPy】全面解析NumPy随机数生成器:使用numpy.random的实用技巧

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

产线虚拟现实vr仿真软件开发在线上能全面呈现企业品质和专业度

在数字化浪潮中&#xff0c;上海VR全景场景制作公司凭借其领先的VR全景制作技术&#xff0c;正为各行各业带来前所未有的沉浸式体验。无论是学校企业场地的生动展示&#xff0c;还是汽车内饰与外观的360度全景呈现&#xff0c;我们都能通过VR虚拟现实制作技术&#xff0c;让您的…

斯坦福大学ALOHA家务机器人团队发布了最新研究成果—YAY Robot语言交互式操作系统

ALOHA YAY 演示视频-智能佳 斯坦福的ALOHA家务机器人团队&#xff0c;发布了最新研究成果—Yell At Your Robot&#xff08;简称YAY&#xff09;&#xff0c;有了它&#xff0c;机器人的“翻车”动作&#xff0c;只要喊句话就能纠正了&#xff01; 标ALOHA2协作平台题 而且机器…

SpringSecurity登录和校验流程简述

认证&#xff1a; 验证当前访问系统的是不是本系统的用户&#xff0c;并且要确认具体是哪个用户 授权&#xff1a; 经过认证后判断当前用户是否有权限进行某个操作 一、入门案例实现 搭建springboot工程后&#xff0c;创建启动类和Controller&#xff0c;引入SpringSecurity依…

CCF- CSP 2018.12 - 1.2题 Java语言解题

2018.12-1 小明上学 import java.util.Scanner;public class text01_RedLight {public static void main(String[] args) {Scanner scanner new Scanner(System.in);int r scanner.nextInt();int y scanner.nextInt();int g scanner.nextInt();int n scanner.nextInt();in…

springboot 两个相同类型的Bean使用@Resouce加载

问题描述 有两个相同类型的Bean 使用Service等注解注入或者Bean注入启动以后报错&#xff1a; qualifying bean of type com.fasterxml.jackson.databind.ObjectMapper available: expected single matching bean but found 2提示有相同的类型两个。 解决 * 每个Bean Resour…

第15章-超声波避障功能 HC-SR04超声波测距模块详解STM32超声波测距

这个是全网最详细的STM32项目教学视频。 第一篇在这里: 视频在这里 STM32智能小车V3-STM32入门教程-openmv与STM32循迹小车-stm32f103c8t6-电赛 嵌入式学习 PID控制算法 编码器电机 跟随 15.1-超声波测距 完成超声波测距功能、测量数据显示在OLED屏幕上 硬件介绍 使用&#…

Creo装配体中只显示一部分零部件

从模型树中选中要显示的零部件&#xff0c;也可以结合Ctrl框选的方式选择对象。然后在模型树右击等会弹出选项&#xff0c;点选----即可

AD23中一些好用的功能

1.关闭在线DRC功能&#xff0c;可以避免布线时候一卡一卡的问题&#xff1a; 取消在线DRC的勾选&#xff1a; 2.AD的在线封装库&#xff0c;非常好用&#xff1a; 如何优雅地服用AD 21的在线元件库 – 吴川斌的博客 (mr-wu.cn) 3.如何恢复Altium Designer23默认窗口布局 打开…

小红书推流机制底层逻辑

小红书推流机制底层逻辑 很多做运营的朋友问小红薯怎么玩❓ 小红书的核心逻辑流量是不是玄学❓ 今天就来说说小红书的流量算法机制&#x1f525; ①电脑审核 ②分配初始流量 ③增加流量 ④推荐结束

DINO中为什么教师模型用大图,学生模型用小图

在 DINO&#xff08;可以理解为由DIstillation和NO labels的缩写&#xff09;中&#xff0c;使用不同的图像裁剪策略对教师模型和学生模型进行训练有其特定的原因。具体来说&#xff0c;教师模型使用大图&#xff08;global views&#xff09;&#xff0c;学生模型则同时使用大…

鸿蒙OS开发:【一次开发,多端部署】(音乐专辑主页)

一多音乐专辑主页 介绍 本示例展示了音乐专辑主页。 头部返回栏: 因元素单一、位置固定在顶部&#xff0c;因此适合采用自适应拉伸&#xff0c;充分利用顶部区域。专辑封面: 使用栅格组件控制占比&#xff0c;在小尺寸屏幕下封面图与歌单描述在同一行。歌曲列表: 使用栅格组…

LVM和配额管理

文章目录 一、LVM1.1 LVM概述1.2 LVM的管理命令1.3 创建LVM的过程第一步&#xff1a;先创建物理卷第二步&#xff1a;创建逻辑卷组 / 扩容第三步&#xff1a;创建逻辑卷 / 扩容对ext4文件系统的管理 1.4 删除LVM 二、磁盘配额2.1 磁盘配额概述2.2 磁盘配额命令2.3 磁盘配额设置…

从ZooKeeper切换到ClickHouse-Keeper,藏着怎样的秘密

本文字数&#xff1a;7772&#xff1b;估计阅读时间&#xff1a;20 分钟 作者&#xff1a;博睿数据 李骅宸&#xff08;太道&#xff09;& 小叮当 本文在公众号【ClickHouseInc】首发 本系列前两篇内容&#xff1a; 从ES到ClickHouse&#xff0c;Bonree ONE平台更轻更快&a…

vue3学习(三)

前言 继续接上一篇笔记&#xff0c;继续学习的vue的组件化知识&#xff0c;可能需要分2个小节记录。前端大佬请忽略&#xff0c;也可以留下大家的鼓励&#xff0c;感恩&#xff01; 一、理解组件化 二、组件化知识 1、先上知识点&#xff1a; 2、示例代码 App.vue (主页面) …

数据恢复:手机数据恢复,盘点7个有效手机恢复方法

你知道吗&#xff0c;超过 70% 的智能手机用户都曾有过数据丢失的经历&#xff1f;如果你曾经丢失过手机中的重要文件&#xff0c;别担心&#xff0c;本文有解决办法。在本文中&#xff0c;我们将告诉你如何使用简单的步骤恢复手机中丢失的数据。无论你是不小心删除了文件还是手…

go使用letteravatar生成圆形透明头像图标

官网地址&#xff1a;GitHub - disintegration/letteravatar: Letter avatar generation for Go 我对其中函数改了一下&#xff0c;支持多个字符&#xff0c;效果如下&#xff1a; func TestCreateAvatar(t *testing.T) {GenerateAvatar("Bird Fish", 0, "Bird…

stm32 FLYMCU串口刷机:程序文件不是0x8000000和0x20000000区域的”解决办法。

你想使用串口刷机&#xff0c;用FLYMCU &#xff0c; 刷入的bin 文件是不带地址的&#xff0c;得刷入HEX文件 才可以&#xff0c;因为程序并不知道是从0x8000000开始的&#xff0c; 如果必须得刷入bin 那就得用stm32Cube programmer 这个软件 也可以使用ST-LINK&#xff08;S…