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.rhkb.cn/news/331634.html

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

相关文章

2024年汉字小达人活动4个多月开赛:18道历年选择题和答案、解析

根据近年的安排&#xff0c;2024年第11届汉字小达人比赛还有4个多月就启动&#xff0c;那么孩子们如何利用这段时间有条不紊地备考呢&#xff1f;我的建议是两手准备&#xff1a;①把小学1-5年级的语文课本上的知识点熟悉&#xff0c;重点是字、词、成语、古诗。②把历年真题刷…

VTK 数据处理:特征边提取

VTK 数据处理&#xff1a;特征边提取 VTK 数据处理&#xff1a;特征边提取原理实例 1&#xff1a;边界边提取实例 2&#xff1a;模型特征边提取实例 3&#xff1a;利用 vtkFeatureEdges 提取的边界补洞实例 4&#xff1a;利用 vtkFillHolesFilter 补洞 VTK 数据处理&#xff1a…

全局平均池化笔记

全局平均池化&#xff08;Global Average Pooling, GAP&#xff09;是一种用于卷积神经网络&#xff08;CNN&#xff09;中的池化操作&#xff0c;其主要作用和优点包括&#xff1a; 减少参数数量&#xff1a;全局平均池化层将每个特征图通过取其所有元素的平均值&#xff0c;压…

初识Spring Boot

初识Spring Boot SpringBoot是建立在Spring框架之上的一个项目,它的目标是简化Spring应用程序的初始搭建以及开发过程。 对比Spring Spring Boot作为Spring框架的一个模块&#xff0c;旨在简化Spring应用程序的初始搭建和开发过程&#xff0c;以下是Spring Boot相对于传统Spri…

[datawhale202405]从零手搓大模型实战:TinyAgent

结论速递 TinyAgent项目实现了一个简单的Agent智能体&#xff0c;主要是实现了ReAct策略&#xff08;推理调用工具的能力&#xff09;&#xff0c;及封装了一个Tool。 项目实现有一定的疏漏。为了正确运行代码&#xff0c;本次对代码Agent部分进行了简单修改&#xff08;完善…

【Linux】Linux的安装

文章目录 一、Linux环境的安装虚拟机 镜像文件云服务器&#xff08;可能需要花钱&#xff09; 未完待续 一、Linux环境的安装 我们往后的学习用的Linux版本为——CentOs 7 &#xff0c;使用 Ubuntu 也可以 。这里提供几个安装方法&#xff1a; 电脑安装双系统&#xff08;不…

关于burp的intruder返回包空白问题

记录一下被自己蠢笑的问题 burp返回包为空怎么办&#xff0c;在查询无果后经过多次试验&#xff0c;确实没有效果 看那三个点还以为加载呢&#xff0c;攻击完了怎么一个显示没有 于是…… 鼠标到三个点&#xff0c;往下一拉 哈哈哈哈哈哈哈&#xff0c;真是被自己给蠢到了

基于地理坐标的高阶几何编辑工具算法(2)——相交面裁剪

文章目录 工具步骤应用场景算法输入算法输出算法示意图算法原理后处理 工具步骤 选中一个需要裁剪的面&#xff0c;点击“相交面裁剪”工具&#xff0c;多选裁剪模板面&#xff0c;空格执行。 应用场景 常用于基于遥感影像的建筑物几何面编辑。 算法输入 一个待裁剪的面&a…

Mysql 备份恢复 mysqldump与xtrabackup备份

1.1 备份的原因 备份是数据安全的最后一道防线&#xff0c;对于任何数据丢失的场景&#xff0c;备份虽然不一定能恢复百分之百的数据 (取决于备份周期)&#xff0c;但至少能将损失降到最低。衡量备份恢复有两个重要的指标&#xff1a;恢复点目标(RPO) 和恢复时间目标(RTO)&…

vue+elemntui 加减表单框功能样式

<el-form ref"form" :model"form" :rules"rules" label-width"80px"><el-form-item label"配置时间" prop"currentAllocationDate"><div v-for"(item,key) in timeList"><el-date…

实验一:通过路由器实现内外网互联

通过路由器实现内外网互联 一、实验拓扑 相关配置详见下图&#xff0c;内网区域为AR2以内设备&#xff0c;外网区域以AR1和PC1代替进行实验测试。 二、实验要求 通过路由器实现内外网互联&#xff1a; 1.各内网PC可自动获取ip地址&#xff1b; 2.各内网PC可ping通外网PC&…

认知架构 cognitive architecture

Assistants API&#xff1a;以开发人员为中心。 有状态的API&#xff1a;允许存储以前的消息、上传文件、访问内置工具&#xff08;代码解释器&#xff09;、通过函数调用控制其他工具。 认知架构应用的两个组件&#xff1a;&#xff08;1&#xff09;如何提供上下文给应用 &…

【DevOps】深入了解RabbitMQ:AMQP协议基础、消息队列工作原理和应用场景

目录 一、核心功能 二、优势 三、核心概念 四、工作原理 五、交换机类型 六、消息确认 七、持久性和可靠性 八、插件和扩展 九、集群和镜像队列 十、客户端库 十一、管理界面 十二、应用场景 RabbitMQ是一个基于AMQP协议的消息队列中间件&#xff0c;提供高可用、可…

C++ | Leetcode C++题解之第112题路径总和

题目&#xff1a; 题解&#xff1a; class Solution { public:bool hasPathSum(TreeNode *root, int sum) {if (root nullptr) {return false;}if (root->left nullptr && root->right nullptr) {return sum root->val;}return hasPathSum(root->left…

el-table 划入划出方法

<template><div><el-table :data"tableData" style"width: 100%" cell-mouse-enter"handleMouseEnter" cell-mouse-leave"handleMouseLeave"><el-table-column prop"ddd" label"日期2" widt…

【TB作品】stm32单片机读取DS2401程序

DS2401是由Analog Devices公司生产的一种硅序列号芯片&#xff0c;它提供了一个绝对唯一的64位ROM识别码&#xff0c;用于确保可追溯性。以下是对DS2401器件的分析&#xff1a; 特点和优势&#xff1a; 唯一性&#xff1a;每个DS2401芯片都有一个独一无二的64位注册码&#x…

【实际项目精选源码】ehr人力资源管理系统实现案例(java,vue)

一、项目介绍 一款全源码可二开&#xff0c;可基于云部署、私有部署的企业级数字化人力资源管理系统&#xff0c;涵盖了招聘、人事、考勤、绩效、社保、酬薪六大模块&#xff0c;解决了从人事招聘到酬薪计算的全周期人力资源管理&#xff0c;符合当下大中小型企业组织架构管理运…

List Control控件绑定变量

创建基于对话框的mfc项目 添加 List Control控件 右击控件&#xff0c;选择“添加变量” 在初始化对话框代码中增加一些代码 BOOL CMFCApplication3Dlg::OnInitDialog() { //...// TODO: 在此添加额外的初始化代码DWORD dwStyle m_programLangList.GetExtendedStyle(); …

用户态下屏蔽全局消息钩子 —— ClientLoadLibrary 指针覆盖

目录 前言 一、研究 SetWindowsHookEx 的机制 二、概念验证 三、运行效果分析 四、总结与展望 参考文献 原文出处链接&#xff1a;[https://blog.csdn.net/qq_59075481/article/details/139206017] 前言 SetWindowsHookEx 函数帮助其他人员注入模块到我们的进程&#x…

PHP质量工具系列之php_CodeSniffer

PHP_CodeSniffer 是一组两个 PHP 脚本&#xff1a;主脚本 phpcs 对 PHP、JavaScript 和 CSS 文件进行标记&#xff0c;以检测是否违反定义的编码标准&#xff1b;第二个脚本 phpcbf 自动纠正违反编码标准的行为。PHP_CodeSniffer 是一个重要的开发工具&#xff0c;可以确保你的…