二分查找 ,看这一篇就够了

news2024/9/21 0:47:47

 什么是二分查找?

        二分查找(Binary Search)是一种高效的查找算法,适用于在有序数组中查找特定元素。其基本思想是通过逐步缩小查找范围,每次将查找区间减半,从而大大提高查找效率。二分查找的时间复杂度为O(log n),远优于线性查找的O(n)。

        使用二分查找的前提条件是,数组是有序的。

基本实现代码

 public static int binarySearchbasic(int[] arr, int target) {
        int i = 0,j=arr.length-1;//设置两个指针

        while(i <= j) {//当左右指针没有重合时
            int m = (i + j) / 2;//计算中间位置,Java语言的整数除法自动向下取整

            if (arr[m] == target) {//如果找到目标值,返回位置
                return m;
            } else if (arr[m] > target) {//目标值在左半部分
                j = m - 1;
            } else {//目标值在右半部分
                i = m + 1;
            }
        }
        return -1;//如果没有找到目标值,返回-1
    }

代码执行步骤:

         m 代表中间元素,如果目标值小于中间元素,那么直接将j =m-1,找左半部分,反之就找右半部分,如果目标值=中间元素,那么直接找到了,返回索引。如果不符合这三种情况,说明该数组里没有这个元素,直接返回-1.表示没有找到。

        这应该很容易理解,也能大幅提升查找效率。

 问题思考

1.为什么是i<=j而不是i<j? 

        因为i和j是指针,指向数组的第一个元素和最后一个元素,如果要查找的元素刚好是第一个或者最后一个元素 ,当i和j重合时,说明数组中没有目标值,返回-1,这样会导致结果不符,所以要采用<=。

2.(i+j)/2 有没有问题? 

        考虑到可能会int溢出,如果两个数过大,采用除2 就有可能导致出现负数,而且Java语言的int类型是自动向下取整的,有些其他语言是需要你自己做取整的,比如 (0+7)/2 等于 3.5,我们都知道没有3.5这个索引,所以需要取整,改用 (i+j)>>>1,右移一位相当于除以2,效率更高,假如换成其他语言也可以写成右移1位,这样就不需要考虑取整问题,泛用性更好。

改进代码 

        这也是为什么有些大佬的二分查找代码和这个不一样的原因,我们需要再改进一下代码

    public static int binarySearchAdvanced(int[] arr, int target){

        int i = 0,j = arr.length; //将j初始化为数组的长度,这样可以避免数组越界
        while(i < j){//改成< ,因为i和j是指针,指向数组的第一个元素和最后一个元素,当i和j重合时,说明数组中没有目标值,返回-1。
            int m = (i + j) >>> 1;
            if(arr[m] == target)
                return m;
            else if(arr[m] > target)
                j = m;// 改成j = m,因为m可能是第一个元素,此时i=0,j=m,i<j,所以不会进入循环。
            else
                i = m + 1;
        }
        return -1;

    }

改版2号 

    //二分查找平衡版
    public static int binarySearchBalanced(int[] arr, int target){

        int i = 0,j = arr.length;
        while(1< j-i){
            int m = (i + j) >>> 1;
            if (target < arr[m])
                j = m;
            else
                i = m;
        }
        if (i<arr.length && arr[i] == target)
            return i;
        else
            return -1;
    }

 

改进的优点:
  1. 避免数组越界:将 j 初始化为 arr.length,避免了在计算中间位置时可能出现的数组越界问题。
  2. 整数溢出预防:使用 (i + j) >>> 1 替代 (i + j) / 2,有效防止了整数溢出问题。
  3. 逻辑简化:通过调整循环条件和指针移动方式,简化了代码逻辑,使其更易于理解和维护。
  4. 将j初始化为数组的长度,这样可以避免数组越界
  5. 改成< ,因为i和j是指针,指向数组的第一个元素和最后一个元素,当i和j重合时,说明数组中没有目标值,返回-1。
  6. 原来是j = m -1,改成j = m,因为m可能是第一个元素,此时i=0,j=m,i<j,所以不会进入循环。

测试

public static void main(String[] args) {
    int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    System.out.println(binarySearchbasic(arr, 5)); // 输出: 4
    System.out.println(binarySearchbasic(arr, 11)); // 输出: -1

    System.out.println(binarySearchAdvanced(arr, 5)); // 输出: 4
    System.out.println(binarySearchAdvanced(arr, 11)); // 输出: -1
}

        通过以上示例,可以看到二分查找算法的高效性和实用性。改进后的实现不仅提高了代码的健壮性,还增强了其可读性和维护性。

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

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

相关文章

B样条曲线测试

实验效果&#xff1a; 绿色为A*规划的路径&#xff0c;蓝色为Bspline曲线 介绍 对A* 生成的路径进行B样条&#xff08;A* 和Bspline都是佬们写好的&#xff0c;我直接拿来用&#xff09; 样条曲线相关可参考文章&#xff1a;详解样条曲线&#xff08;上&#xff09;&#x…

基于LaMA-Factory微调llama3.1-8B

大模型的训练目前主要分为Pre-training和Post-training&#xff0c;受限于资源算力等原因&#xff0c;实际工作中更多用到的是SFT。 对于普通用户来说SFT仍然具备较高的门槛&#xff0c;需要了解一定的理论基础&#xff0c;准备用于微调的数据&#xff0c;由于不同基座模型相应…

xilinx通用RAM或者FIFO设计

1、在 Vivado 中&#xff0c;XPM&#xff08;Xilinx Parameterized Macros&#xff09;是 Xilinx 提供的一组预定义的、参数化的硬件描述语言 (HDL) 宏模块&#xff0c;用于简化设计流程和提高设计效率。XPM 模块通常用于实现常见的功能&#xff0c;比如存储器&#xff08;RAM/…

PWR电源控制(低功耗模式)

1 PWR简介 1 程序后面是空循环&#xff0c;即使不用也会耗电&#xff0c;所以有了低功耗&#xff08;例如遥控器&#xff09; 2 也要保留唤醒模式&#xff0c;如串口接收数据中断唤醒&#xff0c;外部中断唤醒&#xff0c;RTC闹钟唤醒&#xff0c;在需要工作是&#xff0c;ST…

docker装大米cms(damicms)各种cms可用相同办法

1.docker pull 拉取镜像文件 docker pull medicean/vulapps:base_lamp 2.使用docker运行 docker run -d -p 8080:80 medicean/vulapps:base_lamp 3将需要搭建的 CMS 项目源码放到 kali 中&#xff0c;这里以 damiCMS 为例 查看容器id docker ps 4进入dmCMS 所在目录&#…

基于Java+SpringBoot+Vue的新闻稿件管理系统

基于JavaSpringBootVue的新闻稿件管理系统 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接&#x1f345; 哈…

利用高德API获取整个城市的公交路线并可视化(四)

副标题&#xff1a;公共汽电车站点覆盖率——以厦门市公交线路为例 书接上回&#xff0c;我们有了公交的线路、站点数据&#xff0c;并同时对数据质量进行了校验&#xff0c;但是不同城市情况不同&#xff0c;需要看当地对公交交通数据的开放程度&#xff0c;部分城市建设的有…

Linux系统运行模式以及链接文件

一.Linux系统运行模式 如上图所示&#xff0c;可以使用runlevel这条命令去查看当前系统的运行模式。 如上图所示&#xff0c;可以使用这条命令使得机器以字符模式启动。 如上图所示&#xff0c;可以使用这条命令使得机器以图像化界面启动。 二.链接文件 链接文件类型&#xff…

Aigtek电压放大器的技术指标是什么

电压放大器是一种电路&#xff0c;用于将低电压信号放大为高电压信号。它在电子、通信、音频和视频等领域广泛应用。下面是电压放大器电路的一些特点。 放大倍数高&#xff1a;电压放大器的主要功能是将输入信号的幅度放大到所需的输出电压。因此&#xff0c;电压放大器的一个重…

(Postman)接口测试基础应用

目录 ​编辑 1.简介与分类 2.接口测试流程及用例设计 3. 实战接口介绍 4.postman的简介&#xff0c;安装&#xff0c;注册 5.get请求和响应页签详解 6. 问题​编辑 1.环境变量和全局变量&#xff1a;globals--全局变量 2.接口关联 1.简介与分类 1.接口测试是测试系统组…

重头开始嵌入式第三十四天(数据库二)

sqlite3的一些补充 目录 sqlite3的一些补充 1.事物 2.连接&#xff0c;联合 3.触发器 4.子查询 1.事物 数据库事务是数据库管理系统执行过程中的一个逻辑单位&#xff0c;它由一系列对数据库的操作组成。 一、事务的特性 1. 原子性&#xff08;Atomicity&#xff09…

移动端设计规范:提升用户体验的核心要素

随着移动互联网的普及&#xff0c;移动端设计已成为用户体验的关键一环。设计师不仅需要考虑视觉美感&#xff0c;还必须确保设计符合用户操作习惯&#xff0c;提高用户的操作效率。本文将探讨移动端设计的核心规范&#xff0c;帮助设计师打造出既美观又实用的应用界面。 一、…

uniapp动态页面API

目录 uni.setNavigationBarTitle动态设置标题 uni.showNavigationBarLoading为标题添加加载动画与uni.hideNavigationBarLoading停止加载动画 ​编辑 uni.setNavigationBarColor用于设置导航栏的颜色&#xff0c;包括背景颜色和文字颜色。这对于自定义应用的主题和风格非常有…

高质量的小间距LED显示屏有什么表现

随着企业对宣传和品牌形象提升的需求日益增长&#xff0c;LED显示屏凭借其立体化宣传和低成本优势&#xff0c;逐渐成为企业宣传的重要工具。近年来&#xff0c;小间距LED显示屏在市场上逐渐普及&#xff0c;生产厂家和产品种类也不断增加。面对如此众多的选择&#xff0c;许多…

合法的数字货币有哪些类型

合法数字货币的类型 一、常见的合法数字货币类型 比特币&#xff08;Bitcoin&#xff0c;BTC&#xff09;&#xff1a;作为世界上第一个数字货币&#xff0c;由中本聪在 2009 年创造。其特点包括去中心化、匿名性和安全性较高&#xff0c;市值较高。以太坊&#xff08;Ethereu…

智能家居系统(基于STM32F103C8T6标准库+FreeRTOS+Qt串口开发实现)

视频演示&#xff1a;基于STM32F103C8T6标准库FreeRTOSQt串口开发实现的智能家居项目_哔哩哔哩_bilibili 基于STM32F103C8T6标准库FreeRTOSQt串口开发实现的智能家居项目: https://pan.baidu.com/s/1f41gAfOOnlcQoKoMx3o84A?pwd6j2g 提取码: 6j2g 注&#xff1a;本项目为学习完…

WPS中JS宏使用说明(持续优化...)

前言 好久没发文章了&#xff0c;今天闲来无事发篇文章找找之前的码字感觉。 正文 最近在写教案&#xff0c;发现之前的技术又可以派上用场了。就是JS&#xff0c;全称JavaScript&#xff0c;这个语言太强大了&#xff0c;我发现WPS里的宏现在默认就是JS。功能选项如下图&…

Android 打开 GBK项目如何设置成UTF-8

1.标题 今天打开一个eclipse老项目&#xff0c;编码格式为GBK&#xff0c;Android studio导入项目报错&#xff0c;本人想到一个方案就是批量修改文件格式从 GBK到 UTF-8&#xff0c;这样可以一键解决问题 2.开发脚本 使用前请备份代码 使用前请备份代码 使用前请备份代码…

关于paddleocr文字识别内存泄漏的问题

最近在写一个小项目&#xff0c;需要使用paddleocr进行文字识别&#xff0c;然后发现存在严重的内存泄漏&#xff0c;运行时间越长&#xff0c;cpu和内存的占用率就越高。很容易导致程序的崩溃。 代码的主要逻辑如下&#xff1a; import os import numpy as np from paddleocr…

深入理解GAN网络

Generative Adversarial Networks创造性地提出了对抗训练来代替人工指定的loss。之前的文章初步理解了一下&#xff0c;感觉还是不到位&#xff0c;在这里再稍微深入一点。 交叉熵cross entropy 鉴别器是GAN中重要的一部分&#xff0c;鉴别器和生成器交替训练的过程就是adver…