二分查找算法介绍(边界值、循环条件、值的变化、二分查找的原理、异常处理)

一、二分查找法原理介绍

        二分查找是经典的查找算法之一,其原理也非常简单。

        对于已排序的数组(假设是整型,如果非整型,如果有排序和大小比较的定义,也可以使用二分查找),我们每次判断中间值与目标值的大小,从而排除另外半边。

       如下图所示,我们每次可以排除现有数组的一半及以上数据,也就是说,二分查找,利用了排除的原理。

二、二分查找的3个关键数据

        left:确定左边界,比如上图原数据的0。

        right:确定右边界,比如上图原数据的8。(有些题解,会用9表示,则right仍是右边界,只是此边界无法取到)

        middle:从中间开始判断,每次排除左边或右边的所有数据。

三、left、right的取值条件

        在此先说明一个重点

        left、right是限定数组的,每一次排除元素,都要保证得到的新数组,没有重复、缺失。【缺失可能出错,重复会导致复杂情况】

        缺失的情况其实一般不会出现。

        我们疑虑的,主要是这个问题:

        当 middle > 目标值时, 排除右边区域,那么:

        right = middle,还是

        right = middle - 1呢?

        如果用 right = middle,因为有重复数据,会不会更加保险呢?

        别急,接着往下看。

四、二分查找边界值处理【关键是,仅1个元素的数组】

        抽象left、right的选值,因为这并非重点,如果明白边界值处理,就能理解left、right选值和while循环条件的原理。

        第一,空数组【】

        假设我们有一个空数组,必定无所需元素,所以直接返回null。

        第二,1元素数组【a】

        假设数组中,只有一个元素a,此时只要判断a==目标值否,就能知道数组中是否有值。

        第三,其它情况。

        我们已知left、right是限定数组的,那么,如果目前数组的中心值middle,刚好等于目标值,就能返回答案。【这是最简单的情况,而且不用考虑1、2情况】

        但是常常会出现的问题是:

        1.数组中没有目标值。

        2.很可能一直迭代到left==right,或者left+1=right时,才得到目标值。【而第2个情况,又得从while条件里,找正确与否。】

                不考虑 left+2 == right ,或者 left+3 == right 的原因

        left+2 == right:中间值middle,可以等于

        ( left + right ) / 2                      比如【1,4,6】

       无论排除左边,还是右边,最后都剩下1元素数组【1】或者【6】

        left+3 == right : 中间值middle,为

        left+1【(left+left+3)除以2,化简】  比如【1, 4, 6, 9】

        那么,左边排除后,剩下【6,9】,即新问题【 left+1 == right 】的解决。

        右边排除后,剩下【1】,即为单元素问题。

        我们忽略第1个问题,因为如果解决了第2个问题,第1个问题也是迎刃而解。

                考虑2种情况, left == right,和 left+1 == right

        正如“第二,1元素数组【a】”所说,只要判断中间值 middle == (left+right)/2 == left与目标值的关系,就能知道数组中有无目标值。

        我们统一一种算法【满足开头所说的重点】:

        1. middle大于目标值,则舍弃右边,所以   right = middle - 1;

        2. middle小于目标值,则舍弃左边,所以   left = middle + 1;

        3. middle = (left + right) /2;

        这种算法可行吗?

        显然,当 left 恰好为 right 时,middle正好等于 left,恰好可以判断。

        所以,在单元素中满足。

        对于 left +1 == right呢?

        假设我们刚进入这个数组,那么 middle = left 【 ( left+left+1 ) / 2 】

        那么,经过判断,要不就说明 middle > 目标值,数组中无目标值。

        要不就是, middle < 目标值,判断右边的最后1个元素。

        这一步结束后,结果即1元素数组【a】的解法(或者成功判断)

        所以,本题满足。

五、while的循环条件

        我们已经了解left、right的取值,最后的重点是,while条件该如何处理?

        其实一般都知道,left < right 时,一般都可以继续执行,可是 left == right 时,该怎么办呢?

        结合上面的思路,其实一下就能看出来,如果 left == right, 不就恰好是 1元素的数组吗?

        那用 left <= right 作为循环条件,会不会无限循环呢?

        不会,因为我们把middle也排除了,做到了无重复,所以这个问题不算复杂。

六、异常处理

        考虑异常。

        数组元素重复

        最经典的,就是每一次比较middle后,使:

        left = middle;

        right = middle;

        出现的两种情况:

        假设现在有 1元素数组【a】。

        middle、left、right都指向a,无论a比目标值大、小,只要不等于,那么left、right会永远指向a,陷入死循环。

        当然,也有的情况是 2元素数组【a,b】

        left指向a, right指向b,此时middle指向a。

        并且,a比目标值小。

        此时,left = middle。

        而middle又是 left+right的二分之一,恰好是left,又是死循环。

        解决:

        特地判断 left == right, 和 left+1 == right两种情况。【那么代码就不够简洁,反而复杂了。】

        循环条件异常:

        对于 left初值为0, right初值为len-1。

        如果条件是 left < right ,明显会缺失数据。【不再解释】

        如果right初值为len呢?

        这是常常出现的问题,此时我们可以发现,right指向空元素。

        为了保持数据结构的统一性,必须在接下来的更新里,使得right永远指向空元素【不一定是无值,但是要使 right 指向的区间,已经被排除过。】

        这时,在排除时,就可以:

        right = middle。

        那么循环条件也明显了,如果 left <= right,那么在最后,一定会出现面对 空集合 ,却一直判断的情况。【注:空集合是我们更新后,新数组为null, 而在原数组中,(left+right )/2指向的元素,仍然有值】

七、结语

        总之,一定要做好 数组 更新的一致性,做好了这个,就能解题了。

         我是蚊子码农,如有补充或者疑问,欢迎在评论区留言。个人的知识体系可能没有那么完善,希望各位多多指正,谢谢大家。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

单位企业是如何禁用USB接口的(公司禁止USB接口的三大方法)

在当前信息化时代&#xff0c;单位企业对于数据安全的重视程度日益增加&#xff0c;尤其是防止通过USB接口导致的数据泄露和恶意软件传播。 为了构建一个更加安全的办公环境&#xff0c;许多企业采取措施禁用USB接口。 以下是公司禁止USB接口的三大常用方法&#xff1a; 1. 部…

AI绘画Stable Diffusion最新整合包,开源免费 AI 绘图工具神器,解压即用!

写在前面 众所周知现在的AI绘画可谓是热火朝天&#xff0c;前有国外的Midjourney&#xff0c;后有国内各大平台推出的 各种AI工具等&#xff0c;但是目前的这些线上的AI绘画都会有生成次数、时长等限制&#xff0c;有时候还得排队等待出图&#xff0c;所以免费开源的 Stable D…

大话设计模式解读01-简单工厂模式

本系列的文章&#xff0c;来介绍编程中的设计模式&#xff0c;介绍的内容主要为《大话设计模式》的读书笔记&#xff0c;并改用C语言来实现&#xff08;书中使用的是.NET中的C#&#xff09;,本篇来学习第一章&#xff0c;介绍的设计模式是——简单工厂模式。 1 面向对象编程 …

989.数组形式的整数加法

对于非负整数 X而言&#xff0c;x的数组形式是每位数字按从左到右的顺序形成 的数组。例如&#xff0c;如果 X1231&#xff0c;那么其数组形式为[1,2,3,1]。 给定非负整数 X的数组形式 A&#xff0c;返回整数 X 的数组形式, #include <stdio.h> #include <stdlib.h>…

【面试经典150题】删除有序数组中的重复项||

目录 一.题目解析二.解法一三.解法二 一.题目解析 首先我们先看一下题目描述&#xff1a; 删除数组中的重复项的升级版要求&#xff0c;一个升序数组序列中&#xff0c;相同的元素最多出现两次。 二.解法一 首项我们先来看一种比较繁琐坑比较多的解法&#xff1a; class S…

JCR一区级 | Matlab实现TCN-BiLSTM-MATT时间卷积双向长短期记忆神经网络多特征分类预测

JCR一区级 | Matlab实现TCN-BiLSTM-MATT时间卷积双向长短期记忆神经网络多特征分类预测 目录 JCR一区级 | Matlab实现TCN-BiLSTM-MATT时间卷积双向长短期记忆神经网络多特征分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.JMatlab实现TCN-BiLSTM-MATT时间卷积双…

Spring Boot 整合开源 Tess4J库 实现OCR图片文字识别

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

Python | 试卷刷题and基础笔记

1.下列转义字符中&#xff0c; 属于“回车”含义的是 \n 换行 \r 回车 2.for循环遍历字典 在Python中&#xff0c;你可以使用for循环来遍历字典的键&#xff08;keys&#xff09;、值&#xff08;values&#xff09;或者键-值对&#xff08;items&#xff09;。下面是三种遍历…

RPA机器人未来的发展方向和趋势

在数字经济的大背景下&#xff0c;众多企业重新寻找自身的创新驱动力&#xff0c;数字化转型需求迎来爆发式增长。在强劲的数字化转型需求以及国家政策的推动下&#xff0c;RPA行业即将迎来更为有利的发展局面。Gartner预测&#xff0c;到2025年&#xff0c;超级自动化市场规模…

【JavaScript】---DOM操作1:获取元素

【JavaScript】—DOM操作1&#xff1a;获取元素 文章目录 【JavaScript】---DOM操作1&#xff1a;获取元素一、什么是DOM&#xff1f;1.1 概念1.2 图例演示 二、查找HTML元素2.1 getElementById()2.2 getElementsByTagName()2.3 getElementsByClassName()2.4 querySelector()2.…

成人本科毕业论文怎么写?分享自己的经验

撰写成人本科毕业论文是一个系统而深入的过程&#xff0c;以下是我个人的经验分享&#xff0c;希望能帮助你更好地完成这一任务&#xff1a; 1. 明确论文选题 兴趣与专长&#xff1a;选择自己感兴趣且有一定专长的领域&#xff0c;这样更容易深入研究。可行性&#xff1a;确保…

NocoDB开源的智能表格详解-腾讯文档本地替代品

文章目录 一、介绍二、docker-compose部署三、登录NocoDB四、NocoDB手册1. 创建项目2. 收集统计表2.1 添加字段2.2 编辑字段2.3 字段类型2.4 发布表格 3.创建表单3.1 创建表单3.2 分享表单3.3 填写检测单 4.创建看板5.创建画廊 一、介绍 可作为腾讯文档的本地电子表格替代品&a…

Springboot作业管理系统的设计与实现-计算机毕业设计源码98119

目 录 摘要 1 绪论 1.1研究背景 1.2研究现状 1.3springboot框架介绍 1.4论文结构与章节安排 2 作业管理系统系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能性分析 2…

论文摘要一般要写些什么内容?

论文摘要通常需要包含以下几个关键内容&#xff1a; 研究背景与目的&#xff1a;简要介绍研究的背景信息&#xff0c;包括研究领域的重要性、当前的研究现状以及存在的问题。然后&#xff0c;清晰地阐述研究的目的、研究问题或研究假设&#xff0c;让读者明白研究的出发点和意图…

python 各种画图(2D 3D)-1 _matplotlib 官方网站笔记

背景 需利用python进行3D可视化处理&#xff0c;用于分析python得到的数据的正确性。 知识学习 python高阶3D绘图---pyvista模块&#xff0c;mayavi模块&#xff0c;pyopengl模块&#xff0c;MoviePy模块基础使用-CSDN博客 python用于3D绘图的模块比较多&#xff0c;pyvist…

Apache Doris 基础 -- 数据表设计(表索引)

1、索引概述 索引用于帮助快速过滤或搜索数据。目前&#xff0c;Doris支持两种类型的索引:内置智能索引和用户创建的二级索引。 内置智能索引 排序键和前缀索引:Apache Doris基于排序键以有序的方式存储数据。它为每1024行数据创建一个前缀索引。索引中的键是当前1024行组的…

2024码蹄杯初赛 拔河(非二分解法)

AK选手前来补充一发邪典&#xff08;水数据&#xff09;写法 题面&#xff1a; 简单来说就是给你一个序列&#xff0c;让你选择一段连续区间&#xff0c;使得这个区间平均值最大&#xff0c;同时区间长度大于等于F。 很显然对于区间求和直接用前缀和优化到O(1)&#xff0c;但是…

代码随想录 day 26

回溯 组合总和 题意&#xff1a;一个无重复元素的整数数组&#xff1b;一个目标整数target&#xff1b; 找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff1b;并以列表形式返回。candidates 的同一个数字可以无限制重复被选取。 思路&#xff1a;因为…

半导体光子电学期末笔记2: 光子晶体 Photonic crystals

光子晶体概述 光子晶体定义和分类 [P4-5] 光子晶体是一种在一维、二维或三维空间内周期性排列的多层介质。这些结构通过在光子尺度上排列的重复单元&#xff0c;可以对光进行调控和控制。具体来说&#xff0c;光子晶体是指那些在空间上具有周期性排列的介质结构&#xff0c;它…

文心一言 VS 讯飞星火 VS chatgpt (273)-- 算法导论20.2 8题

八、假设设计了这样一个 proto-vEB 结构&#xff0c;其中每个簇数组仅有 u 1 4 u^\frac{1}{4} u41​ 个元素。那么每个操作的运行时间是多少&#xff1f;如果要写代码&#xff0c;请用go语言。 文心一言&#xff1a; 如果你修改了 van Emde Boas (vEB) 树中的簇大小&#xf…