Java查找算法之二分查找
二分查找是一种查询效率非常高的查找算法。又称折半查找。
一、算法思想
有序的序列,每次都是以序列的中间位置的数来与待查找的关键字进行比较,每次缩小一半的查找范围,直到匹配成功。
一个情景:将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
二、举例图示

要查找的数为21。
第一次将头指针和尾指针分别放置头尾,middle放在中间。将21与中间的56进行比较。21<56,应在左边。
第二次将尾指针放在56得到前一位,middle放在中间。将21与中间的19进行比较。21>19,应在右边。
第三次将头指针放在19的后一位,middle放在中间。将21与21比较,符合查找成功!
三、二分查找优缺点及使用条件
优点是比较次数少,查找速度快,平均性能好;
其缺点是要求待查表为有序表,且插入删除困难。
因此,折半查找方法适用于不经常变动而查找频繁的有序列表。
使用条件:查找序列是顺序结构,有序。
四、算法实现
package recursion; /**
* @author zsh
* @company wlgzs
* @create 2019-02-16 10:11
* @Describe 二分查找的两种实现
*/
public class BinarySearch { /**
* 循环实现二分查找
* @param arr 待查找的数组
* @param key 待查找的数
* @return key在数组中的索引位置
*/
static int binary1(int[] arr,int key){
//头指针初始位置
int low = 0;
//尾指针初始位置
int high = arr.length -1;
//定义middle指针位置
int middle = 0;
//头尾交叉 || key大于最大值 || key小于最小值,说明未找到
if (low > high || key > arr[high] || key < arr[low]){
return -1;
} while (low <= high){
//防止数据溢出
middle = (low + high) >>> 1;
if (arr[middle] > key){
//middle所对应的值比key大,key应该在左边区域
high = middle -1;
}else if (arr[middle] < key){
//middle所对应的值比key小,key应该在有边区域
low = middle +1;
}else {
return middle;
} } //最后仍然没有找到,则返回-1
return -1;
} /**
* 递归实现二分查找
* @param arr 待查找的数组
* @param low 头指针所在位置
* @param high 尾指针所在位置
* @param key 待查找的数
* @return key在数组中的索引位置
* 算法分析:
* 找重复:
* 找变化量:
* 找出口:头尾交叉 || key大于最大值 || key小于最小值
*/
static int binary2(int[] arr,int low , int high ,int key){ //头尾交叉 || key大于最大值 || key小于最小值,说明未找到
if (low > high || key > arr[high] || key < arr[low]){
return -1;
}
//定义middle指针位置,防止数据溢出
int middle = (low + high) >>> 1; //middle所对应的值比key大,key应该在左边区域
if (arr[middle] > key){
binary2(arr,low,middle-1,key);
}else if (arr[middle] < key){
//middle所对应的值比key小,key应该在有边区域
binary2(arr,low+1,high,key);
}else {
return middle;
} //最后仍然没有找到,则返回-1
return -1;
} public static void main(String[] args) {
int[] arr = new int[]{5,13,19,21,37,56,64,75,80,88,92};
System.out.println(binary1(arr,21));
System.out.println(binary1(arr,21));
} }
五、时间复杂度和空间复杂度
时间复杂度:
最坏的情况下两种方式时间复杂度一样:O(log2 N)
最好情况下为O(1)
空间复杂度:算法的空间复杂度并不是计算实际占用的空间,而是计算整个算法的辅助空间单元的个数
非递归方式:
由于辅助空间是常数级别的所以:空间复杂度是O(1);
递归方式:
递归的次数和深度都是log2 N,每次所需要的辅助空间都是常数级别的:空间复杂度:O(log2N )
Java查找算法之二分查找的更多相关文章
- 数据结构与算法之PHP查找算法(二分查找)
二分查找又称折半查找,只对有序的数组有效. 优点是比较次数少,查找速度快,平均性能好,占用系统内存较少: 缺点是要求待查表为有序表,且插入删除困难. 因此,折半查找方法适用于不经常变动而查找频繁的有序 ...
- python实现查找算法:二分查找法
二分查找算法也称折半查找,基本思想就是折半,和平时猜数字游戏一样,比如猜的数字时67,猜测范围是0-100,则会先猜测中间值50,结果小了,所以就会从50-100猜测,中间值为75,结果大了,又从50 ...
- python数组查找算法---bisect二分查找插入
1 实例 这个模块只有几个函数, 一旦决定使用二分搜索时,立马要想到使用这个模块 [python] view plaincopyprint? import bisect L = [1,3,3,6,8, ...
- Java中的查找算法之顺序查找(Sequential Search)
Java中的查找算法之顺序查找(Sequential Search) 神话丿小王子的博客主页 a) 原理:顺序查找就是按顺序从头到尾依次往下查找,找到数据,则提前结束查找,找不到便一直查找下去,直到数 ...
- java 13-1 数组高级二分查找
查找: 1.基本查找:数组元素无序(从头找到尾) 2.二分查找(折半查找):数组元素有序 pS:数组的元素必须有顺序,从小到大或者从大到小.以下的分析是从小到大的数组 二分查找分析: A:先对数组进行 ...
- 【算法】二分查找法&大O表示法
二分查找 基本概念 二分查找是一种算法,其输入是一个有序的元素列表.如果要查找的元素包含在列表中,二分查找返回其位置:否则返回null. 使用二分查找时,每次都排除一半的数字 对于包含n个元素的列表, ...
- javascript数据结构与算法---检索算法(二分查找法、计算重复次数)
javascript数据结构与算法---检索算法(二分查找法.计算重复次数) /*只需要查找元素是否存在数组,可以先将数组排序,再使用二分查找法*/ function qSort(arr){ if ( ...
- C语言查找算法之顺序查找、二分查找(折半查找)
C语言查找算法之顺序查找.二分查找(折半查找),最近考试要用到,网上也有很多例子,我觉得还是自己写的看得懂一些. 顺序查找 /*顺序查找 顺序查找是在一个已知无(或有序)序队列中找出与给定关键字相同的 ...
- 算法入门——二分查找,旅行商问题,大O表示法
一. 算法入门 博主在市面上发现了很多,很多有关书算法的书籍,但是真正能够让初学者易懂的算法书籍,只是一点点,以下我讲以 Aditya Bhargava写的一本关于算法的入门书籍,为参考,这本书非常的 ...
随机推荐
- Python面向对象:继承和多态
继承与多态简介: 继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写. 动态语言的鸭子类型特点决定了继承不像静态语言那样是必须的. ...
- prometheus and collectd and docker
sudo docker run --name prometheus -d -v /data/prometheusdata/prometheus.yml:/etc/prometheus/prometh ...
- Ball---hdu5821(排序)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5821 题意:有n个盒子,每个盒子又一个值 a[i] 如果 a[i] 大于 0 说明盒子里面有 1 个颜 ...
- 聊一聊Linux中的工作队列
2018-01-18 工作队列是Linux内核中把工作延迟执行的一种手段,其目的不同于软中断,软中断是提高CPU的响应,尽可能的缩短关中断的时间:而工作队列主要目的是节省资源,其比较适合很微小的任务, ...
- CSS表单设计
今天我们开始学习<十天学会web标准(div+css)>的css表单设计,包含以下内容和知识点: 改变文本框和文本域样式 用图片美化按钮 改变下拉列表样式 用label标签提升用户体验 一 ...
- 【Pyton】【小甲鱼】正则表达式(一)
正则表达式学习: >>> import re >>> re.search(r'FishC','I love FishC.com!') <_sre.SRE_Ma ...
- backreference Oracle正則表達式中的反向引用
这是Oracle对正則表達式的backreference的描写叙述 从定义中能够看到,当匹配表达式中已()的形式将一个子串包括起来.后面就能够以\? 的形式来引用.\1相应第一个(),\2相应第二 ...
- matlab做曲线拟合
python 做曲线拟合 https://blog.csdn.net/qq_16583687/article/details/72723708 matlab做拟合函数,可以在命令行输入:数据x,数据y ...
- Gcc ------ gcc的使用简介与命令行参数说明
gcc的使用简介与命令行参数说明 2011年06月19日 20:29:00 阅读数:10221 2011-06-19 wcdj 参考:<GNU gcc嵌入式系统开发 作者:董文军> (一) ...
- 获取Let`s Encrypt证书的三种方式
1,acme.sh 方式 1)获取acme脚本 curl https://get.acme.sh | sh 2)开始获取证书 acme.sh强大之处在于,可以自动配置DNS,不用去域名后台操作解析记录 ...