飞道的博客

【算法学习】四 二分法查找(折半法或者折半查找)

684人阅读  评论(0)

前言

社长,一个爱学习,爱分享的程序猿,始终相信,付出总会有回报的。知识改变命运,学习成就未来。爱拼才会赢!
程序猿学社的GitHub,已整理成相关技术专刊,欢迎Star:
https://github.com/ITfqyd/cxyxs

社长,4年api搬运工程师,之前做的都是一些框架的搬运工作,做的时间越长,越发感觉自己技术越菜,有同感的社友,可以在下方留言。现更侧重于java底层学习和算法结构学习,希望自己能改变这种现状。
为什么大厂面试,更侧重于java原理底层的提问,因为通过底层的提问,他能看出一个人的学习能力,看看这个人的可培养潜力。随着springboot的流行,大部分的开发,起步就是springboot。也不看看springboot为什么简单?他底层是如何实现的。为什么同样出来4年,工资差别都很大?这些问题都值得我们深思(对社长自己说的)。
api工程师,顶天了,最多达到某些公司中级工资上限,很难突破高级这道坎。希望我们大家成就更好的自己。回想起往事,不会后悔。

目录

前言:

一 什么是二分法查找?

二 实现思路

分三种情况:

学习中遇到问题后,我们应该如何处理?

二分法查找2种实现方式

非递归方式

递归方式

性能对比分析:


一 什么是二分法查找?

二分法也可以叫折半法,他是一种一种查询效率较高的方法。适用于数据量较大时,但是需要数据先排好顺序。
小结:遇到效率高,我们就应该引起注意,就跟ArrayList一样,他的查询效率高,但是只适合于单线程,因为他线程不安全。遇到类似的问题,我们应该多反问(社长的一万个为什么),多思考。多想想,他是不是有什么缺陷或者前提。

二 实现思路

一个班的成绩有高有低,从低到高排序 50 56 60 70 80 90 92 94 98
因为是二分,每次取一般,这里先定义三个变量header mid footer,注意是对应值的下标。

分三种情况:

第一种: 相等,表示找到了。
我要找的值就是80。Mid对应的值,刚好与我要查的值相等。就没有必要继续往下走。
第二种:需要查找的值小于mid,footer=mid-1
划重点上一次的mid是4,值为80,为什么上面画的图没有80?
在第一种情况里面已经判断过,那我们为什么还需要再判断一次勒,你们说是不是这个道理。觉得对的社友扣666。
有些有着求知欲的社友,又开始问了,header为,footer为3,mid咋是1,不应该是1.5吗?
社长我也不知道为什么是1。(0+3)/2 就是1。可以先去查看一下基础。
第三种:需要查找的值大于mid,header=mid+1

学习中遇到问题后,我们应该如何处理?

我发现有不少社友都继承了社长的一万个为什么,首先,积极提出问题,这点值得表扬。社长工作也有一段时间了,遇到问题,发现,大致的人群可以分为3种。
按王者荣耀的术语做一个级别划分
第一种,不敢请教别人,怕暴露自己的真实水平,同事之间,遇到不少这种,建议,有可能你一个问题,卡了几天,别人给你一分钟指导,就帮你解决了。 青铜选手
第二种,敢于请教,但不思。 遇到问题,需要虚心的请教别人,但是,自己不多思,多查。 白银选手
第三种:多思多查敢于请教。 黄金选手

二分法查找2种实现方式

非递归方式


  
  1. package com.fyqd.test.sort;
  2. /**
  3.  * Description:不使用递归方式
  4.  * Author: 程序猿学社
  5.  * Date:  2020/1/18 21:38
  6.  * Modified By:
  7.  */
  8. public  class  BinaryTest {
  9.      public static int binary(int[] array, int value{
  10.          int low =  0;
  11.          int high = array.length -  1;
  12.          while (low <= high) {
  13.              int middle = (low + high) /  2;
  14.              if ( value == array[middle]) {
  15.                  return middle;
  16.             }
  17.              if ( value > array[middle]) {
  18.                 low = middle +  1;
  19.             }
  20.              if ( value < array[middle]) {
  21.                 high = middle -  1;
  22.             }
  23.         }
  24.          return  -1;
  25.     }
  26.      public static void main(String[] args{
  27.          //50 56 60 70 80 90 92 94 98
  28.          int[] a = { 505660708090929498};
  29.          int score =  60;
  30.          int  value = binary(a,score);
  31.          if( value ==  -1){
  32.             System. out.println( "没有找到,继续加油!");
  33.         } else{
  34.             System. out.println( "找到了你真棒,分数为"+score+ ",索引为"+ value);
  35.         }
  36.     }
  37. }

递归方式


  
  1. package com.fyqd.test.sort;
  2. /**
  3.  * Description:使用递归方式
  4.  * Author: 程序猿学社
  5.  * Date:  2020/1/18 21:38
  6.  * Modified By:
  7.  */
  8. public  class  BinaryTest1 {
  9.      public static int binary(int[] array, int value{
  10.          int header =  0;
  11.          int footer = array.length -  1;
  12.          return search(array, value,header,footer);
  13.     }
  14.      public static int search(int[] array, int value,int header,int footer){
  15.          if(header > footer){
  16.              return  -1;
  17.         }
  18.          int middle = (header + footer) /  2;
  19.          if ( value == array[middle]) {
  20.              return middle;
  21.         } else  if ( value > array[middle]) {
  22.             header = middle +  1;
  23.              return search(array, value,header,footer);
  24.         } else{
  25.             footer = footer -  1;
  26.              return search(array, value,header,footer);
  27.         }
  28.     };
  29.      public static void main(String[] args{
  30.          //50 56 60 70 80 90 92 94 98
  31.          int[] a = { 505660708090929498};
  32.          int score =  980;
  33.          int  value = binary(a,score);
  34.          if( value ==  -1){
  35.             System. out.println( "没有找到,继续加油!");
  36.         } else{
  37.             System. out.println( "找到了你真棒,分数为"+score+ ",索引为"+ value);
  38.         }
  39.     }
  40. }

注意:使用递归方式,一定要给出终止条件

性能对比分析:

名称 时间复杂度 空间复杂度 描述
普通排序 O(N) O(1) 通过for循环一个个查找
二分法非递归方式 O(logN) O(1)  
二分法使用递归方式 O(logN) O(1*logN) 每次调用开销1,重复调用logN次,每次需要额外的开辟空间

二分法非递归方式性能最优,为什么

《算法学习》 一:为什么要学习算法?时间复杂度

历史算法文章推荐:

《算法学习》二 冒泡排序分析

【算法学习】三 选择排序分析

后记

程序猿学社的GitHub,欢迎Star:
https://github.com/ITfqyd/cxyxs
觉得有用,可以点赞,关注,评论,留言四连发。


转载:https://blog.csdn.net/qq_16855077/article/details/104041031
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场