二分查找

二分查找总结 一、概述 1、定义 二分查找是一种广泛使用的搜索算法,主要用于在有序数组(一般是升序,后面的内容也只是针对升序情况)上查找元素 2、主要思想 二分查找算法背后的主要思想是充分利用元素之间的有序性、以及数组的随机访问特性,每次都与查找区间的中间元素比较大小,根据比较结果不断将查找范围缩小一半(采用分治策略,剪枝?),直到元素被找到,或者,查找区间被缩小为0 3、工作流程 将中间元素... 阅读详情

二分查找算法

描述

二分查找也称折半查找(Binary Search),它是一种效率非常高效的查找方法。但是折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
那它的效率有多高呢?还在给一个直观的数据做个展示吧,在一个1到2亿的个有充数组内查找一个给定值,使用二分查找需要多少次呢?最多也只需要28次。

##时间复杂度
二分查找的时间复杂非常的高,那高效到什么程序呢?
假设数据大小是n,每次查找都会缩小为原来的一半,即为除2操作,最坏情况下,直到查找区间缩小为空,才停止
被查找到的大小区间变化为
n,n/2,n/4,n/8,…,n/(2的k次方)
这是一个等比数列,n/(2的k次方)=1,可求得k=log2n,所以时间复杂度为O(logn)
logn是一种非常恐怖的数量数量级,即便n非常大,logn也很小,
比如2的30次方大约是10亿,在这10亿个数中使用二分查找,最多也就30次。

举个粟子

以“1,3,5,7,8,10,13”这组数据为例

public class BinarySearch {

  /**
   * 最简单的二分查找情况,在无重复的元素中去查找给定值
   *
   * @param data
   * @param value
   * @return
   */
  public int search(int[] data, int value) {

    if (null == data || data.length == 0) {
      return -1;
    }

    int low = 0, mid, high = data.length - 1;

    while (low <= high) {
      mid = low + (high - low) / 2;
      // 如果当前中间值等于组定值,则返回
      if (data[mid] == value) {
        return mid;
      }
      // 如果当前中间值大于组定值,说明在左区间查找
      else if (data[mid] > value) {
        high = mid - 1;
      }
      // 如果当前中间小于给定值,则说明在右区间查找
      else {
        low = mid + 1;
      }
    }

    return -1;
  }
}

在这里插入图片描述


二分查找的变体问题

变体1,查找每个值等于给定值的元素。

之前的数据中是不允许重复的,但在真实的数据中,数据是会存在重复的。
现在的问题就变成了,在一个出现重复的元素中,查找给定值。
以数组“1,3,5,7,7,8,10,13”,查找第一个出现7的为例。

public class BinarySearchFirst {

  /**
   * 在一个重复的数组内,查找值等于给定值的元素,重复需要返回第一个
   *
   * @param data
   * @param value
   * @return
   */
  public int search(int[] data, int value) {

    if (null == data || data.length == 0) {
      return -1;
    }

    int low = 0, mid, high = data.length - 1;

    while (low <= high) {
      mid = low + (high - low) / 2;
      // 当查找到当前元素为给定元素
      if (data[mid] == value) {
        // 由于存在重复,需在检查是否为第一次出现
        //为0,则肯定为首次出现,前一个元素不与当前元素相同,也说明首次出现
        if (mid == 0 || data[mid - 1] != value) {
          return mid;
        }
        // 非第一次出现,继续向左搜索
        else {
          high = mid - 1;
        }
      }
      // 如果当前值中间值大于给定值,则在左区间查找
      else if (data[mid] > value) {
        high = mid - 1;
      }
      // 如果当前中间件小于给定值,则在右区间搜索
      else {
        low = mid + 1;
      }
    }

    return -1;
  }
}

在这里插入图片描述


变体2,查找最后一个值等于给定值的元素

以数组“1,3,5,7,7,8,10,13”,查找最后一个出现7的为例。

public class BinarySearchLast {

  /**
   * 在一个重复的数组内,查找最后一个值等于给定值的元素
   *
   * @param data
   * @param value
   * @return
   */
  public int search(int[] data, int value) {

    if (null == data || data.length == 0) {
      return -1;
    }

    int low = 0, mid, high = data.length - 1;

    while (low <= high) {
      mid = low + (high - low) / 2;

      // 1,如果区间中间件等于查找到的值
      if (data[mid] == value) {
        // 如果已经为最后值,说明为最后一个,
        // 如果后一个元素与给定值不同,也说明为最后一个
        if (data[mid] == high || data[mid + 1] != value) {
          return mid;
        }
        // 如果非最后一个,则在右区间继续查找
        else {
          low = mid + 1;
        }
      }
      // 如果区间中间值大于给定值,则说明需要继续在左区间查找
      else if (data[mid] > value) {
        high = mid - 1;
      }
      // 区间中间值小于给定值,则需要继续右区间中查找
      else {
        low = mid + 1;
      }
    }

    return -1;
  }
}

在这里插入图片描述


变体3,查找每个大于等于组定的元素

以数组“1,3,5,7,7,8,10,13”,查找最后一个出现7的为例。


public class BinarySearchEqualOrGreaterThan {

  /**
   * 查找第一个大于等于给定值的元素
   *
   * @param data
   * @param value
   * @return
   */
  public int search(int[] data, int value) {

    if (null == data || data.length == 0) {
      return -1;
    }

    int low = 0, mid, high = data.length - 1;

    while (low <= high) {
      mid = low + (high - low) / 2;

      // 当前区间中间值如果大于等于给定值
      if (data[mid] >= value) {
        // 如果为首元素或者前一个元素小于给定元素,则结束
        if (mid == 0 || data[mid - 1] < value) {
          return mid;
        }
        // 否则继续向左区间查找
        else {
          high = mid - 1;
        }
      }
      // 如果当前区间中间值小于给定值,则在右区间查找
      else {
        low = mid + 1;
      }
    }

    return -1;
  }
}

在这里插入图片描述

变体4,查找最后一个小于等于给定值的元素

以数组“1,3,5,7,7,8,10,13”,查找最后一个出现7的为例。

public class BinarySearchEqualOrLessThan {

  /**
   * 查找最后一个小于等于给定值的元素
   *
   * @param data
   * @param value
   * @return
   */
  public int search(int[] data, int value) {

    if (null == data || data.length == 0) {
      return -1;
    }

    int low = 0, mid, high = data.length - 1;

    while (low <= high) {
      mid = low + (high - low) / 2;

      // 如果当前区间中间值小于等于给定值
      if (data[mid] <= value) {
        // 如果当前为最后一个,则直接返回
        // 或者当前区间中间值的后一个元素大于给定元素,也返回
        if (mid == high || data[mid + 1] > value) {
          return mid;
        }
        // 否则继续在右区间继续查找
        else {
          low = mid + 1;
        }
      }
      // 如果当前区间中间值大于给定值,则在左区间中查找
      else {
        high = mid - 1;
      }
    }

    return -1;
  }
}

在这里插入图片描述

关于二分查找的处理注意事项

二分查找算法写起来非常的烧脑,很容易因为细节处理不好而产生bug,
容易出现的错误:终点条件,区间上下界更新方法,返回值选择。

二分查找算法 摘要 二分查找,一个很经典的算法。但是真正理解透彻这个算法却不容易。下面记载一点自己学习二分查找的心得。 参考 正文: 二分查找有N多种写法,有各种各样的形式,选一种合适自己,自己能够理解记住的才是最好的。下面分享一个我比较赞的版本。 对于最最最原始的二分查找,即给出一个Key,查找出key值的索引号。 注意注意注意!!最经典的二分查找对返回来的索引号没有任何要求,只要其对应的值是... 阅读详情

相关推荐

【二分查找】学习总结

二分查找:  (1) 一般的二分查找:          例如:找球号问题: 在某一国度里流行着一种游戏。游戏规则为:在一堆球中,每个球上都有一个整数编号i(0             这就是普通的二分查找,把所有的球号存入ans[ ]数组了,从小到大排序,然后二分查找,假设共n个球吧(数组中0----n-1)            首先边界 fir=0,end=n-1,

nyist_飘谊 2541

二分查找的最多比较次数

二分法细节,还有一直疑惑的,最大查找次数细节

m0_56147044的博客 1万+

Unity 常见问题 之 打包编译的报错 Unable to sign the application; please provide passwords!

Unity 常见问题 之 打包编译的报错 Unable to sign the application; please provide passwords! 目录 Unity 常见问题 之 打包编译的报错 Unable to sign the application; please provide passwords! 一、简单介绍 二、问题描述 三、原因分析 四、可能的解决方法 方法一:取消 Keystore 设置即可 方法二:重新添加 Keystore 相关设置 一...

仙魁XAN 1万+

Java面试系列文:算法、数据结构、基础设计模式

大厂面试高频基础面试题。建议复制到自己的笔记当中,跳槽前必备! 要求 能够用自己语言描述二分查找算法 能够手写二分查找代码 能够解答一些变化后的考法 1.算法描述 前提:有已排序数组 A(假设已经做好) 定义左边界 L、右边界 R,确定搜索范围,循环执行二分查找(3、4两步) 获取中间索引 M = Floor((L+R) /2) 中间索引的值 A[M] 与待搜索的值 T 进行比较 ① A[M] == T 表示找到,返回中间索引 ② A[M] > T,中间值右侧的其它元素都大于 T,无需比较,中间索引左

技术专家 834

ACR 磁共振安全手册 2024 更新版:全面保障 MRI 安全实践

MR 环境:MR 系统周围的三维空间,包含法拉第屏蔽体积和 9 高斯线,医疗设备在此区域可能因暴露于 MR 设备产生的电磁场而构成危险,需进行访问控制以降低风险MR 受控访问区域:MR 系统周围的局部定义区域,包含 MR 环境(包括其静磁场),访问仅限于授权人员MR 抛射物区域:围绕 MRI 系统的 IV 区区域,铁磁物体在此有成为抛射物的风险图一 磁共振环境:场地规划与区域划分。

楚山之石的博客 2600

LIN总线CAPL函数实战——动态控制报文发送(linDeactivateSlot与linActivateSlot)

本文深入解析了LIN总线测试中动态控制报文发送的核心CAPL函数linDeactivateSlot与linActivateSlot的实战应用。通过详细拆解函数参数、生效范围及限制,并结合故障注入、功耗测试等实际场景的代码示例,指导测试工程师在仿真LIN主节点时,灵活调度报文发送,实现高效自动化测试。

weixin_29255731的博客 347

【基础算法】二分查找

UnityC# 二分查找

plaxbsga的专栏 769

反激开关电源设计全解析:从CCM/DCM原理到PCB布局实战

开关电源作为现代电子设备的能量转换核心,其核心原理是通过高频开关动作实现高效的电能变换。反激拓扑因其结构简单、成本低廉且易于实现电气隔离,成为小功率离线式电源的主流选择。其技术价值在于通过变压器耦合实现能量存储与传递,解决了安全隔离与多路输出等关键需求,广泛应用于充电器、适配器及家电供电等场景。本文聚焦反激电路,深入剖析其CCM与DCM两种工作模式的原理差异及选型考量,并结合伏秒平衡定律与RCD钳位等热词,详解从变压器计算到MOSFET选型的完整工程设计流程。

weixin_31951365的博客 340

算法:二分查找法

引入 二分查找是一种非常简单易懂的快速查找算法,生活中到处可见。 例子一 我们现在来做一个猜字游戏。我随机写一个 0 到 99 之间的数字,然后你来猜我写的是什么。猜的过程中,你每猜一次,我就会告诉你猜的大了还是小了,直到猜中为止。你来想想,如何快速猜中我写的数字呢? 假设我写的数字是 23,猜数过程如下。(如果猜测范围的数字有偶数个,中间数有两个,就选择较小的那个。) 例子2 假设有1000条订单数据,已经按照订单金额从小到大排序,每个订单金额不同,并且最小单位是元。我们现在想知道支付存在金额等

OceanStar的博客 9445

哨兵2号遥感影像解析全流程:步骤、算法与AI应用详解

未来,多源数据融合与边缘计算技术的应用将进一步拓展遥感解析的边界。波段合成:选择10m分辨率波段(如B2、B3、B4、B8)进行Layer Stacking,生成多光谱影像。| 分类与识别 | Scikit-Learn、PyTorch | SVM、CNN、K-Means聚类 | 地块分类、目标检测 || 数据预处理 | SNAP、Sen2Cor | 大气校正、几何校正 | L2A产品生成、格式转换 || 波段融合 | ENVI、GDAL | Layer Stacking、重采样 | 多光谱影像合成 |

zhz5214的博客 2710

sysrepo 开发者指南(一个基于libyang与支持rpc的数据库)

sysrepo 开发者指南(一个基于libyang与支持rpc的数据库) 日志记录 默认情况下,所有 Sysrepo 日志记录都处于关闭状态。如果启用,日志消息有 3 种输出。它们可以写入stderr、由 处理syslog或简单地传递给回调。 请务必注意,启用 Sysrepo 日志记录也会修改libyang日志记录设置。错误消息被视为标准 Sysrepo 错误,其他严重性较低的消息完全隐藏。要更改此行为,只需在启用 Sysrepo 日志记录后调整libyang日志记录设置。 此外,几乎每个 Sysrepo

weixin_43489394的博客 9225

二分查找的次数

第1题 二分查找有序列表 [2,10,25,35,40,65,70,73,75,81,82,88,100] 如果查找元素75,需要依次比较 70 81 73 75 (0+12)/2 索引6 第1次 (7+12)/2 索引9 第2次 (7+8)/2 索引7 第3次 (8+8)/2 索引8 第4次 第2题 二分查找有序列表 [1,2,3,4,5,6,7,8,9,10,11,12,13,14] 如果查找元素4,需要依次比较 7 3 5 4 (0+13)/2 索引6 第1次 (0+5)/2 索引2

前端精髓 9199

手机如何高效辅助林业调查

手机如何高效辅助林业调查 很多林业工作者将栅格类型的地形图处理后导入平板电脑,在林地使用平板电脑加载小班矢量图,辅助林业调查。但是,如果没有地形图底图,这种方法可能就有难度,而且最重要的是,大部分林地工作者没有能力配置平板电脑。大凡林业基层工作者在林地调查时,除调查记录本等部分纸质材料外,都必然携带手机和水杯,此外其他设备已经成为累赘,尤其是炎热的夏季在杂灌丛生的林地进行调查作业。因此,使用手机...

xu780820的博客 3077

二分查找之红蓝二分查找

/ 目标值在左半部分} else {left = mid;// 目标值在右半部分left : -1;// 返回最后一个满足条件的值的索引。

xiaoxie8023的博客 2326

从宏观到街道:如何利用七普数据为WorldPop人口栅格做“本地化”校准?

本文探讨了如何利用第七次全国人口普查(七普)数据对WorldPop人口栅格进行本地化校准,以提高街道级别的人口分布精度。通过分析数据偏差、选择适当的技术路线和工具(如Arcgis和栅格计算器),文章详细介绍了从宏观到街道的校准实践,帮助规划公共卫生资源和优化城市基础设施。

janckywong963的专栏 511

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

优选算法《二分查找》

在之前的学习当中我们已经初步了解过了二分查找的整体逻辑以及二分查找,接下来我们在本篇当中将系统的来学习二分查找的使用方式以及在什么情况下可以使用二分查找。在之前的学习当中我们了解到的二分查找是要求在有序的数组当中当数组元素有序时才能使用,但是其实这只是二分查找最朴素的使用场景,接下来我们将学习更多的二分查找的使用场景。相信通过被本章的学习之后你会有所收获,一起加油吧!!!

mljy.博客 2496

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

详解二分查找

一.为什么要使用二分查找 当有一个排好顺序的数组,我们需要知道我们要找的值是否在当前数组中,那么我们就需要自己实现一个查找的方法来进行实现,那么如果我们找的数在最后一个位置n处,假设这个n非常大,那么我们要是一次一次进行比较的话就要比较n次,这样就会显得非常慢,那么有没有一种相较于普通查找速度更快的方法吗,那就是二分查找。 二.二分查找的解释 二分查找:也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。

weixin_47651920的博客 5939

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

二分查找最坏查找次数_二分查找 事半功倍

前言:“Simplicity is the soul of efficiency.”简洁是效率的灵魂。-- Enda Kenny, TaoiseachYou clicked onthe third article written by ADOSCIE.你激动的点开了ADOSCIE的第三篇文章。But you realized that you aren’t familiar with ...

weixin_34294809的博客 2227

c++二分查找

由于此时只剩下两个数了,所以我们不再二分了,直接判断A[8]是否等于17,或者A[9]是否等于17即可。//表示要在A[1]至A[N]范围查找x。因为我们要查找的数是3,小于A[mid],所以我们下次要在A[L]至A[mid]范围内查找,//查询数组A是否包含x。因为要查找的数是17,大于A[5],所以我们应该在A[5]至A[10]这一段查找,令L=1, R=10, 表示我们用在A[1],A[2],...A[10]里面查找。1、当要查找的数小于A[1]或者大于A[N],返回"no",否则进入二分查找过程。

浪子回头 1733

算法——二分查找

算法——二分查找一、二分查找的框架二、基本二分查找的两种写法1.定义target在闭区间[left,right]2.定义target在左闭右开区间[left,right)三、寻找边界的二分查找1.寻找左侧边界的二分查找写法1写法22.寻找右侧边界的二分查找写法1写法2题目:leetcode704.二分查找leetcode35.搜索插入位置思路1.暴力解法2.二分法 一、二分查找的框架 使用条件: 数组为有序数组 数组中无重复元素(一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的) int bi

weixin_61015911的博客 1371

Leetcode之二分查找

向后看一眼对于这种情况,当我们通过二分查找,找到第一个等于target的元素的时候,需要看一下mid右边的值是否也等于target,如果是,则我们需要继续对[mid+1,high]进行二分查找,如果不是,则说明mid就是我们要找的元素。题目链接解题思路参考上面的二分查找的变形,我们可以分别找到第一个大于等于target的下标和最后一个等于target的下标,然后返回这两个下标即可。

古承风的博客 1041

简单二分查找、复杂二分查找与跳表

1.查找的分类 1.1 查找表 用于查找的数据集合称之为查找表,它由同一类型的数据元素(或记录)组成,可以是一个数组或者链表等数据结构。对查找表经常进行的操作一般有四种: 1.查询某个特定的数据是否在查找表中。 2.检索满足条件的某个特定的数据元素的各种属性。 3.在查找表中插入一个数据元素。 4.从查找表中删除某个数据元素。 1.2 静态查找表与动态查找表 如果一个查找表的操作只涉及到1和2的操作,则无需动态地修改查找表,此类查找表称之为静态查找表,反之称之为动态查找表。 适合静态查找表的查找方法有:顺序

编程使我快乐 937

二分查找单值 二分查找范围

二分查找单值 二分查找范围二分查找二分查找单值二分范围查找 二分查找 二分查找,用来查找已经排序的序列,时间复杂度为logN,是一个比较好查找方法; 二分查找单值 关于二分查找的一些注意事项: 1 int mid = l + (r - l) / 2;对比mid = (l + r) / 2; 如果l与r值比较大,后面容易溢出。 2 while (l <= r) 这里有== 号,如果没有,如果剩...

AMDmiss的博客 888
上一篇: 学习笔记-数据结构与算法-归并排序
下一篇: leetcode 33. 搜索旋转排序数组
null_null_bug
博客等级 码龄7年 72粉丝 71原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值