算法实现的要求:

折半查找法又称为二分查找法,这种方法对待查找的列表有两个要求:

1:必须采用顺序存储结构
2:必须按关键字大小有序排列

算法思想:

将表中间位置记录的关键字与查找关键字进行比较如果两者相等,则查找成功,否则利用中间位置记录将表分成前后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表

重复上述查找过程,直到找到满足条件的记录,则查找成功,或直到子表不存在为止,则查找不成功

使用java实现该算法:

算法实现方法:

1:前提要求:有已排序数组A,[因为在查找的过程中是根据下标进行的]2:定义左边界L,右边R,确定搜索范围,循环执行二分查找3:获取中间索引M=(L+R)/2,如果是小数,一般默认向下取整4:中间索引的值A[M]与带搜索的值T进行比较
A[M]==T,返回中间索引
A[M]>T,中间值右侧的其他元素都大于T,无需比较,中间索引左边去找,M-1,设置为右边界,重新查找
A[M]<T,中间值左侧的其他元素都小于T,无需比较,中间索引右边去找,M+1设置为左边界,重新查找5:当L>R时,表示没有找到,应结束循环

代码如下所示:

package bin_find;import java.util.Scanner;public class bin_find {public static void main(String[] args) {int arr[] = {4, 10, 18, 23, 45, 68, 199};Scanner scanner = new Scanner(System.in);System.out.println("请输入你要查找的数:");int x = scanner.nextInt();int result= bin_research(arr,x);if(result!=-1){System.out.println("你要查找的数已找到,它是数组的第"+(result+1)+"个元素");}else{System.out.println("你要查找的数不存在");}}public static int bin_research(int arr[], int x) {int L = 0;int R = arr.length - 1;while(L<=R) {//不要写到循环外面了,因为每查找一次,中间索引的位置也需要变化int M = (L + R) / 2;if (x > arr[M]) {L = M+1;} else if (x < arr[M]) {R = M - 1;} else if (x == arr[M]) {return M;}}return -1;}
}

输出:

请输入你要查找的数:
23
你要查找的数已找到,它是数组的第4个元素

整数溢出现象:

package bin_find;public class bin_find2 {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);}
}

输出:

1073741823
-536870913

之所以会出现负数的原因:是因为在计算机中,是根据二进制进行运算的,逢二进一,由于最高位表示符号位,当它为1时,该数即为负数!

对该过程不熟悉的小伙伴,可以去看我写的这篇文章

解决整数溢出问题:

上述代码中产生溢出的原因是由于:当要查找的数在右子表时,此时:r最初为整数的最大值-1不变,而l的值增大到了r/2的大小,因此即使他两相加除2,在计算机中,是根据二进制进行运算的,逢二进一,由于最高位表示符号位,当它为1时,该数即为负数,那么解决溢出的核心就是改变m的值,但所谓的改变,并不是将m的值真正的改变,而是通过变换表达式等等,去调整m的大小

方法1:通过调整数学表达式

方法如下:

代码如下:

package bin_find;public class bin_find2 {public static void main(String[] args) {int l=0;int r=Integer.MAX_VALUE-1;int m=l+(r-l)/2;//当要查找的数在左子表时:System.out.println(m);//当要查找的数在右子表时:l=m+1;m=l+(r-l)/2;System.out.println(m);}
}

输出:

1073741823
1610612735

方法2:通过>>>运算符

>>>表示无符号右移运算符也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0,移动的是二进制位,但他们的操作数必须是整数,[当被操作的数是整数时]右移一位有除二的效果,因此对于上述溢出现象,右移一位既能够避免最高位[符号位]为1,导致该数为负数的现象,而且正好借用它右移一位有除二的效果,还简化了数学表达式;

修改如下:

package bin_find;public class bin_find2 {public static void main(String[] args) {int l=0;int r=Integer.MAX_VALUE-1;int m=(r+l)>>>1;//当要查找的数在左子表时:System.out.println(m);//当要查找的数在右子表时:l=m+1;m=l+(r-l)>>>1;System.out.println(m);}
}

输出:

1073741823
1073741823

对于上述两种做法均可以解决整数溢出问题,不过我们更加推荐第二种,因为它的效率比较高!

练习题:

有一个有序表为 1,5,8,11,19,22,31,35,4045,89,50 当分查找值为48的结点时,查找成功需要比较的次数
[来源于:京东实习生招聘]

答案为:4次

这里需要强调的点就是:当子表的元素个数为偶数时,如果题目没有强调,那么我们默认选择靠左边的元素为中间数

使用二分法在序列 1,4,6,7,15,33,39,50,64,78,75,81,89,96 中查找元素81 时,需要经过()比较
[来源于:美团点评校招]

答案为:4次

在拥有128个元素的数组中二分查找一个数,需要比较的次数最多不超过多少次 [来源于:北京易道博识社招]

答案为:7次

方法1:
上述题目相当于为2^n=128,n的值为多少?

方法2:
使用128一直不断的除2,直到变为1,只需要计算除2的次数即可

方法3:
使用计算器,问题转变为log2^128,不过需要知道该计算机是以多少为底,下图为Windows10操作系统的计算器,以10为底

运算结果是整数,则该整数即为最终结果

运算结果是小数,则舍去小数部分,整数加一为最终结果

折半查找算法[二分查找法]算法的实现和解决整数溢出问题~相关推荐

  1. 数据结构与算法-查找算法(二分查找,插值查找,斐波那契(黄金分割法)查找)

    查找算法 以下三种算法的基本思想相同,都是利用递归来寻找 二分查找 思路分析 1.首先确定该数组的中间下标,min = (left + right) / 2 2.然后让需要查找的的数findVal和a ...

  2. php折半查找算法,二分查找 [折半查找] 算法 PHP 版

    查找表:就是同一类型的数据元素构成的数据集合 有静态表和动态表 本文实现PHP版的二分查找算法[本算法仅用于顺序存储的查找表] /** * Created by PhpStorm. * User: 1 ...

  3. 数据结构三大查找算法(二分查找、插值查找、斐波那契数列查找)C语言实现

    文章目录 查找 二分查找(折半查找) 插值查找 斐波拉契查找 总结: 查找 查找是在大量的信息里面寻找一个特定的信息元素 (1)静态查找和动态查找: 静态或者动态都是针对查找表而言的.动态表指查找表中 ...

  4. 查找算法——二分查找(原理+源码)

    1,原理 二分查找又称折半查找,只适用于有序数组.二分查找原理很简单,针对有序数组的查找效率也很高.具体原理为,每次拿目标数值(以下用value表示)与数组中间位置的数据(以下用arry[mid]表示 ...

  5. 查找算法——二分查找【代码实现】

    伪代码 递归 // initially called with low = 0, high = N-1BinarySearch(A[0..N-1], value, low, high) {// inv ...

  6. java 二分查找_计算机入门必备算法——二分查找法

    1.引言 笔者对于计算机的研究一直停滞不前,近期想对一些算法进行复习和进一步的研究,每天都会更新一个新的算法,算法有难有易,层层递进.不希望能学的有多么高深,只希望在一些最基本的算法上有编码的思路,或 ...

  7. 顺序查找与二分查找算法

    顺序查找算法 顺序查找是非常简单常用的查找算法,基本思路:从第一个元素m开始逐个与需要查找的元素x进行比较,当比较到元素值相同(即m=x)时返回元素m的下标,如果比较到最后都没有找到,则返回-1.该算 ...

  8. 递归法实现折半查找(二分查找)

    题目 递归法实现折半查找(二分查找) 分析 设立low代表数组最小端的数组下标,high代表数组最大端的数组下标,mid代表数组中间值的数组下标 查询数字number与mid进行比较,有四种情况: 1 ...

  9. Java有序表查找:折半查找、二分查找、差值查找和斐波那契查找

    Java有序表查找:折半查找.二分查找.差值查找和斐波那契查找     [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article/details/51 ...

最新文章

  1. X5同层播放器应用实践
  2. ASP.NET MVC
  3. html标记表示超链接,HTML常见标签学习
  4. H3C交换机设置DHCP中继,配合Linux 服务器为多VLAN提供DHCP地址分配服务
  5. (15)css常用样式—background背景属性
  6. android 炫酷时间轴,这38款超级炫酷的时间轴特效代码案例,总有一款是你需要的...
  7. kafka使用_Kafka精华问答 | kafka的使用场景是什么?
  8. org.apache.shiro.session.UnknownSessionException: There is no session with id [xxxx]的解决方案
  9. python工资这么高为什么不学-小白入行年薪21万,为什么Python岗位薪资越来越高?...
  10. 如何运行python代码将各个表格的信息集合在一起_如何利用Python编程批量处理Excel来提高日常工作效率!...
  11. 1分钟教会你cad如何转pdf
  12. Oracle 获取当前日期及日期格式
  13. 学生社区(学校交流社区)网站源码推荐
  14. 南航计算机学院院长黄志球简历,南航计算机科学与技术学院导师介绍:沈国华...
  15. 2019年web前端工程师工资有多高
  16. Carla-UE4Editor导入RoadRunner地图文件(保姆级教程)
  17. macOS终端命令行配置网络代理
  18. 计算机硬件管理措施,浅谈计算机硬件的维护与管理措施
  19. Week 5.1 | 左倾红黑树LLRB | Princeton Algorithms
  20. c++文件读取、容器(vector、map)、迭代(iterator)、排序(sort)综合案例

热门文章

  1. jsp在线电影票订购影城管理系统
  2. Linux查看IP以及修改IP地址
  3. 摘自《读者》的哲理短句——爱情篇
  4. Python开发坦克大战
  5. 抓住偷懒的年轻人,味知香想靠预制菜掀起“厨房革命”难
  6. 康孚备份数据库时报错
  7. KLEE--KLEE主要的生成文件解读
  8. android 软键盘遮挡登陆按钮的问题,Android优雅的方式解决软键盘遮挡按钮问题
  9. stop pin/ignore pin/exclude pin/float pin
  10. 《HTTP权威指南》----HTTP报文