二分查找是一种查询效率非常高的查找算法。又称折半查找。

一、算法思想

  有序的序列,每次都是以序列的中间位置的数来与待查找的关键字进行比较,每次缩小一半的查找范围,直到匹配成功。

  一个情景:将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。

二、举例图示

  要查找的数为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查找算法之二分查找的更多相关文章

  1. 数据结构与算法之PHP查找算法(二分查找)

    二分查找又称折半查找,只对有序的数组有效. 优点是比较次数少,查找速度快,平均性能好,占用系统内存较少: 缺点是要求待查表为有序表,且插入删除困难. 因此,折半查找方法适用于不经常变动而查找频繁的有序 ...

  2. python实现查找算法:二分查找法

    二分查找算法也称折半查找,基本思想就是折半,和平时猜数字游戏一样,比如猜的数字时67,猜测范围是0-100,则会先猜测中间值50,结果小了,所以就会从50-100猜测,中间值为75,结果大了,又从50 ...

  3. python数组查找算法---bisect二分查找插入

    1 实例 这个模块只有几个函数, 一旦决定使用二分搜索时,立马要想到使用这个模块 [python] view plaincopyprint? import bisect L = [1,3,3,6,8, ...

  4. Java中的查找算法之顺序查找(Sequential Search)

    Java中的查找算法之顺序查找(Sequential Search) 神话丿小王子的博客主页 a) 原理:顺序查找就是按顺序从头到尾依次往下查找,找到数据,则提前结束查找,找不到便一直查找下去,直到数 ...

  5. java 13-1 数组高级二分查找

    查找: 1.基本查找:数组元素无序(从头找到尾) 2.二分查找(折半查找):数组元素有序 pS:数组的元素必须有顺序,从小到大或者从大到小.以下的分析是从小到大的数组 二分查找分析: A:先对数组进行 ...

  6. 【算法】二分查找法&大O表示法

    二分查找 基本概念 二分查找是一种算法,其输入是一个有序的元素列表.如果要查找的元素包含在列表中,二分查找返回其位置:否则返回null. 使用二分查找时,每次都排除一半的数字 对于包含n个元素的列表, ...

  7. javascript数据结构与算法---检索算法(二分查找法、计算重复次数)

    javascript数据结构与算法---检索算法(二分查找法.计算重复次数) /*只需要查找元素是否存在数组,可以先将数组排序,再使用二分查找法*/ function qSort(arr){ if ( ...

  8. C语言查找算法之顺序查找、二分查找(折半查找)

    C语言查找算法之顺序查找.二分查找(折半查找),最近考试要用到,网上也有很多例子,我觉得还是自己写的看得懂一些. 顺序查找 /*顺序查找 顺序查找是在一个已知无(或有序)序队列中找出与给定关键字相同的 ...

  9. 算法入门——二分查找,旅行商问题,大O表示法

    一. 算法入门 博主在市面上发现了很多,很多有关书算法的书籍,但是真正能够让初学者易懂的算法书籍,只是一点点,以下我讲以 Aditya Bhargava写的一本关于算法的入门书籍,为参考,这本书非常的 ...

随机推荐

  1. Unified Modeling Language

    https://en.wikipedia.org/wiki/Unified_Modeling_Language

  2. [转]基于S2SH框架的项目—antlr-2.7.2.jar包冲突问题

    java.lang.NoSuchMethodError: antlr.collections.AST.getLine()I        org.hibernate.hql.ast.HqlSqlWal ...

  3. getParameter和getAttribute区别

    (1)HttpServletRequest类有setAttribute()方法,而没有setParameter()方法 (2)当两个Web组件之间为链接关系时,被链接的组件通过getParameter ...

  4. SQLServerDBA十大必备工具---让生活轻松点

    原贴:http://www.cnblogs.com/fygh/archive/2012/04/25/2469563.html 国外整理拓展帖:http://weblogs.sqlteam.com/ml ...

  5. 居然上了模板使用排行榜第一 happy一下

    这段时间在学习css和div,顺便把博客给整了一下,然后不小心就上了FFandIE模板使用排行榜第一,happy一下下.不知道这个算不算排名,还是随机刷新.感觉应该是按流量统计的,这段时间有几篇文章一 ...

  6. dedecms如何增加自定义字段

    开源的cms比较好的一点是可以根据自己的需求来开发相应的功能,比如dedecms想要增加一个专家职称字段调用要怎么调用呢? 增加自定义字段:后台找到 “核心” - 频道模型 - 内容模型管理 - 字段 ...

  7. 006-Redis 发布订阅

    Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. Redis 客户端可以订阅任意数量的频道. 下图展示了频道 channel1 , 以及订 ...

  8. PAT 1054 The Dominant Color[简单][运行超时的问题]

    1054 The Dominant Color (20)(20 分) Behind the scenes in the computer's memory, color is always talke ...

  9. this与$scope

    最近在Angular项目中遇到关于controller内使用$scope&this 暴露数据的问题,下面来分析一下: "controller as" 是Angular在1. ...

  10. How to install MVVM Light Toolkit via NuGet

    Here is how you can install MVVM Light Toolkit  via NuGet in an easy way using only Visual Studio. S ...