目录

1、前言​

2、算法描述

3、算法实现

3.1 代码

3.2 测试

3.3 小结

4、解决整数溢出问题

5、相关面试题


1、前言

这里是一个数组,数组里面都是些不重复的数字, 那我现在想要数组里面有没有74这个数字,当然了,我们用肉眼很容易判断最后一个就是74这个数字,一下就可以找到了。

但是计算机它没这么聪明,你让计算机去找这个数字的话,它得从头到尾去对比。

比如我现在要找74这个数字,那计算机就要先看索引0是不是这个数字,不是就再看索引1,还不是,显然在我的这个例子中,计算机要比较32次才能找到74这个数字。

那这个效率高不高呢?也还可以,比较32次就可以找到它,但是,如果我们的这个数组的元素个数特别的多,比如10000,怎么办,最糟糕情况下,你要找的元素正好也是最后一个,那就要比较10000次,这个效率是无法接受的。

因此我们就要使用到本篇博客要介绍的二分查找算法来提高检索效率, 不过呢,二分查找它有个前提,就是我们要查找的这个数组必须是有序的。

2、算法描述

我们现在呢就找128这个数字

前提:

有已排序数组

定义左边界 L、右边界 R,确定搜索范围:

首先我们要确定一个搜索的范围,这个范围一开始就是从0到31。

确定了这个范围以后,我们不是一个一个比较,而是在它这个范围内,挑它中间的值进行比较。

那么它的中间值就是这个索引为15的74,那个这个74和我们要查找的128做一个比较,显然74是小于128的。

数组现在是排好序的,那74左边这些元素就比128小,既然74左边这些都比128小,就不需要再跟128比了。

这样就比我们原来要比较的次数减小了一半,接下来我们就只需要从74右边的这些元素中去找。  

我们在这个范围内再挑一个中间值111,跟128比,小,所以111左边这些也不需要再跟128比了。

以此类推  

次我们找到了128这个数字。我们一共比较了3次。

注:如果我们的左边界 L > 右边界R 时,表示没有找到,应结束循环。

3、算法实现

3.1 代码

package com.jie.binary;/*** @description:二分查找* @author: jie* @time: 2022/2/7 22:08*/
public class binary {public static void main(String[] args) {//声明数组int[] array = {1, 5, 8, 11, 19, 22, 31, 35, 40, 45, 48, 49, 50};//要查找的元素int target = 48;//调用二分查找方法int idx = binarySearch(array, target);//打印System.out.println(idx);}/*** @description:二分查找,找到返回元素索引,找不到返回-1* @author: jie* @time: 2022/2/7 22:12*/public static int binarySearch(int[] a,int t){//定义左边界l,右边界r,中间索引mint l = 0, r = a.length-1, m;//循环查找  条件l<=r说明左边界还没有超过右边界,这时候我们就不断循环查找。while(l <= r){//计算中间索引mm = (l + r) / 2;//如果a[m]==t说明相等,直接返回mif(a[m]==t){return m;//如果大于t,说明索引右边的都不需要比了}else if(a[m] > t){//重新设置右边界r = m-1;//小于t,说明索引左边的都不需要比了}else{//重新设置左边界l = m+1;}}return -1;}}

3.2 测试

有的元素:

没有的元素:  

3.3 小结

  1. 前提:有已排序数组 A(假设已经做好)

  2. 定义左边界 L、右边界 R,确定搜索范围,循环执行二分查找(3、4两步)

  3. 获取中间索引 M = Floor((L+R) /2)

  4. 中间索引的值 A[M] 与待搜索的值 T 进行比较

① A[M] == T 表示找到,返回中间索引

② A[M] > T,中间值右侧的其它元素都大于 T,无需比较,中间索引左边去找,M - 1 设置为右边界,重新查找

③ A[M] < T,中间值左侧的其它元素都小于 T,无需比较,中间索引右边去找, M + 1 设置为左边界,重新查找

  1. 当 L > R 时,表示没有找到,应结束循环

4、解决整数溢出问题

二分查找代码已经演示完了,但是有一个细节我们要注意一下,就是在计算中间索引 M 的时候,我们用的L+R/2这个公式,但是当L和R取值都特别大的时候,它俩相加就有可能超过整数能存储的最大值,从而造成这个整数溢出问题。整数取值范围( -2147483648~2147483647 )

package com.jie.binary;
/*** @description:整数溢出* @author: jie* @time: 2022/2/8 15:06*/
public class IntegerOverflow {public static void main(String[] args) {//左边界int l = 0;//右边界int r = Integer.MAX_VALUE - 1;//中间索引int m = (l+r) / 2;System.out.println(m);//如果查找的中间值的右侧,要修改左边界l = m + 1;m = (l+r) / 2;System.out.println(m);}
}

第一次计算其实还没有问题,虽然R已经非常大了,但是L非常小,所以它俩加起来并不会超过整数存储范围。

但是如果我们要查找的值在中间值右侧,就要修改左边界,这个时候L+R,就会超过整数存储范围,从而造成整数溢出问题。

第一种解决方法:

int m = l + (r - l) / 2;

第二种解决方法:

int m = (l + r) >>> 1;

注:>>> 是移位运算。这种方法在效率上比除法高。

5、相关面试题

5.1 有一个有序表为 1,5,8,11,19,22,31,35,40,45,48,49,50 当二分查找值为 48 的结点时,查找成功需要比较的次数 。

解题口诀:奇数二分取中间,偶数二分取中间靠左

5.2 在拥有128个元素的数组中二分查找一个数,需要比较的次数最多不超过多少次

解题方案:

第一种是

第二种是

二分查找算法学习总结相关推荐

  1. 由二分查找算法学习算法的时间复杂度

    文章目录 二分查找 数据 算法 函数代码 调用函数 大OOO表示法表示算法运行速度 一些常见的大 OOO 运行时间 启示: 二分查找 二分查找是一种算法,其输入是一个有序的元素列表和要查找的元素.如果 ...

  2. list 查找_五千字长文带你学习 二分查找算法

    点击上方"与你一起学算法",选择"星标"公众号 重磅干货,第一时间送达 二分查找的思想 提及二分查找算法,我想大部分人都不陌生,就算不是学计算机的,基本上也都使 ...

  3. Python 二分查找算法

    如果有这样一个列表,让你从这个列表中找到66的位置,你要怎么做? l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76 ...

  4. python 二分查找_二分查找算法总结

    二分查找的思想是通过每次折半快速找到一个数,例如,我们经常玩的游戏猜数字,在0~1000,随便出一个数字98让对方猜,首先猜500,对方给提示比500大还是小,如果数字小于500,就继续猜250,依次 ...

  5. php二分查找算法时间复杂度,一个运用二分查找算法的程序的时间复杂度是什么...

    一个运用二分查找算法的程序的时间复杂度是"对数级别".二分查找是一种效率较高的查找方法,算法复杂度即是while循环的次数,时间复杂度可以表示"O(h)=O(log2n) ...

  6. 二分算法php,使用PHP实现二分查找算法代码分享

    第一种方法: [二分查找要求]:1.必须采用顺序存储结构 2.必须按关键字大小有序排列. [优缺点]折半查找法的优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难.因 ...

  7. python基础一 day17 二分查找算法

    # 什么叫算法 # 计算的方法 : 人脑复杂 计算机简单 # 99 * 13 = 1287 = 13*100 - 13 # 查找 : 找数据 # 排序 : # 最短路径 # 我们学习的算法 都是过去时 ...

  8. python函数教程:Python递归函数 二分查找算法实现解析

    这篇文章主要介绍了Python递归函数 二分查找算法实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.初始递归 递归函数:在一个函数里在调 ...

  9. 关于《算法(第四版 谢路云译)》标准库In、Out、StdOut和StdIn的正确配置和调用经验分享(以BinarySearch二分查找算法为例)

    本人初学<算法(第四版 谢路云译)>有一段时间了,对于初学者按书敲完第一个BinarySearch二分查找算法发现运行错误,我相信大家跟我一样内心是崩溃的.还好经过翻看多个相关论坛以及自己 ...

最新文章

  1. MindInsight张量可视设计介绍
  2. python等号语法错误_Python干货:代码编写规范
  3. 18秋学期计算机基础在线作业2,东大18秋学期《计算机应用基础》在线作业2.pdf...
  4. cojs EX_香蕉 题解报告
  5. mysql获取当前时间的订单_mysql获取当前时间,及其相关操作
  6. Web安全-之文件上传漏洞场景
  7. win10下安装maven
  8. springboot 整合 谷歌 Captcha验证码
  9. 【区块链开发入门】(二) 以太坊的编程接口
  10. 通过Flex布局实现三等分
  11. linux服务器端 postfix+php邮件发送+发件人代发修改配置
  12. 数据仓库十大主题;TeraData金融数据模型
  13. 怎样播放swf文件 swf格式怎么转换成mp3格式
  14. Gavin老师Transformer直播课感悟 - 通过Rasa Interactive对Rasa对话机器人项目实战之ConcertBot源码、流程及对话过程解密(四十三)
  15. 鸢尾花(iris)数据集分析
  16. 【金猿技术展】SSNG多源数据处理技术——运营商手机信令处理系统及平台
  17. 2016年终总结,新的一年新的开始
  18. 一个神奇的软件jide
  19. CPU微架构资源及监测
  20. 移动芯片如何走出“高水平均衡陷阱”?

热门文章

  1. Python+scrcpy+pyminitouch实现自动化(四)——实现语音识别自动打卡机器人
  2. ✨ StarRocks 9 月社区动态
  3. 光之触角——光敏电阻、光敏二极管、光敏三极管与光照发生器
  4. 【Python】PermissionError: [Errno 13] Permission denied: ‘xxx.xlsx‘问题解决
  5. winForm欢迎界面
  6. Driver——同相运算放大器
  7. 使用Unity制作3D驾驶游戏
  8. linux输入法源,kali linux更新源问题 加 输入法安装(示例代码)
  9. 网易电话面试经验——C 游戏服务器开发
  10. 海信信号机后台服务器配置,海信6101信号机功能.docx