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

前言

社长,一个爱学习,爱分享的程序猿,始终相信,付出总会有回报的。 知识改变命运,学习成就未来。爱拼才会赢!
程序猿学社的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,注意是对应值的下标。

aae2f1300f1a6bbd87fcac4babb7e05b.png

1419c059237c679031da0595a85a784f.png

分三种情况:

第一种: 相等,表示找到了。
我要找的值就是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种实现方式

非递归方式

package com.fyqd.test.sort; /** * Description:不使用递归方式 * Author: 程序猿学社 * Date: 2020/1/18 21:38 * Modified By: */ public class BinaryTest { public static int binary(int[] array, int value) { int low = 0; int high = array.length - 1; while (low <= high) { int middle = (low + high) / 2; if (value == array[middle]) { return middle; } if (value > array[middle]) { low = middle + 1; } if (value < array[middle]) { high = middle - 1; } } return -1; } public static void main(String[] args) { //50 56 60 70 80 90 92 94 98 int[] a = {50, 56, 60, 70, 80, 90, 92, 94, 98}; int score = 60; int value = binary(a,score); if(value == -1){ System.out.println("没有找到,继续加油!"); }else{ System.out.println("找到了你真棒,分数为"+score+",索引为"+value); } } }

1419c059237c679031da0595a85a784f.png

递归方式

package com.fyqd.test.sort; /** * Description:使用递归方式 * Author: 程序猿学社 * Date: 2020/1/18 21:38 * Modified By: */ public class BinaryTest1 { public static int binary(int[] array, int value) { int header = 0; int footer = array.length - 1; return search(array,value,header,footer); } public static int search(int[] array, int value,int header,int footer){ if(header > footer){ return -1; } int middle = (header + footer) / 2; if (value == array[middle]) { return middle; }else if (value > array[middle]) { header = middle + 1; return search(array,value,header,footer); }else{ footer = footer - 1; return search(array,value,header,footer); } }; public static void main(String[] args) { //50 56 60 70 80 90 92 94 98 int[] a = {50, 56, 60, 70, 80, 90, 92, 94, 98}; int score = 980; int value = binary(a,score); if(value == -1){ System.out.println("没有找到,继续加油!"); }else{ System.out.println("找到了你真棒,分数为"+score+",索引为"+value); } } }

1419c059237c679031da0595a85a784f.png

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

性能对比分析:

名称时间复杂度空间复杂度描述普通排序O(N)O(1)通过for循环一个个查找二分法非递归方式O(logN)O(1)

二分法使用递归方式O(logN)O(1*logN)每次调用开销1,重复调用logN次,每次需要额外的开辟空间

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

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

历史算法文章推荐:

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

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

后记

程序猿学社的GitHub,欢迎 Star: https:// github.com/ITfqyd/cxyxs
觉得有用,可以 点赞,关注,评论,留言四连发。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值