在Java中常用的查找算法有四种:

1.顺序查找(不要求数组有序,挨个遍历进行比对);

2.二分查找(要求数组有序);

3.插值查找;

4.斐波那契查找

本文使用递归思想带来二分查找及其优化

二分查找思路分析

1.首选确定该数组中间下标 mid = (left + right) / 2;

2.然后让需要查找的数findVal与arr[mid]比较;
2.1 findVal > arr[mid] 说明要查找的数在mid的右边,因此需要递归的向右查找;
2.2 findVal < arr[mid] 说明要查找的数在mid的左边,因此需要递归的向左查找;
2.3 findVal == arr[mid] 说明找到,就返回

递归结束条件

1)找到就结束递归
2)递归完整个数组,仍然没有找到findVal 也需要结束,即left > right

代码如下:

    /*** * @param arr 数组* @param left 左索引   * @param right 右索引* @param findVal 要查找的值* @return 返回所找到值的索引,如果没有则返回-1*/public static int binarySearch(int[] arr, int left, int right, int findVal){if(left > right){return -1;}int mid = (left + right) / 2;int res = arr[mid];if(findVal > res){//向右递归return binarySearch(arr, mid + 1, right, findVal);}else if(findVal < res){return binarySearch(arr, left, mid - 1, findVal);}else{return mid;}}

但上述算法也有缺陷,当数组中有2个相同的值时,则只能返回其中一个的索引,无法返回所有值的索引。如下方法将上述缺陷改进,以数组{1, 8, 10, 89, 1000, 1000, 1000, 1234} 为例,找到所有1000的数组索引:

思路分析:

1.找到mid 索引值时,不要马上返回;

2.向mid 索引值的左边扫描,将所有满足 1000 的元素下标,放到集合ArrayList里;

3.向mid 索引值的右边扫描,将所有满足 1000 的元素下标,放到集合ArrayList里;

4.将ArrayLi返回

方法体如下:

    public static ArrayList<Integer> binarySearch2(int[] arr, int left, int right, int findVal){if(left > right){return new ArrayList<Integer>();}int mid = (left + right) / 2;int res = arr[mid];if(findVal > res){//向右递归return binarySearch2(arr, mid + 1, right, findVal);}else if(findVal < res){return binarySearch2(arr, left, mid - 1, findVal);}else{ArrayList<Integer> resIndexList = new ArrayList<Integer>();//向左扫描int temp = mid - 1;while(true){if(temp < 0 || arr[temp] != findVal){break;}//否则将temp放入到集合中resIndexList.add(temp);temp -= 1; //temp左移}resIndexList.add(mid); //将mid放入//向右扫描temp = mid + 1;while(true){if(temp > arr.length-1 || arr[temp] != findVal){break;}//否则将temp放入到集合中resIndexList.add(temp);temp += 1;}return resIndexList;}}

调用方法如下:

    public static void main(String[] args){int[] arr = {1, 8, 10, 89, 1000, 1000, 1234};// int resultIndex = binarySearch(arr, 0, arr.length-1, 0);// System.out.println(resultIndex);ArrayList<Integer> resultIndex = binarySearch2(arr, 0, arr.length-1, 1000);System.out.println(resultIndex);}

打印结果为:[4, 5]

Java实现二分查找及其优化相关推荐

  1. java实现二分查找-两种方式

    二分查找是一种查询效率非常高的查找算法.又称折半查找.起初在数据结构中学习递归时实现二分查找,实际上不用递归也可以实现,毕竟递归是需要开辟额外的空间的来 辅助查询.本文就介绍两种方法二分查找算法思想有 ...

  2. Java算法 -- 二分查找:查找目标元素最左的位置和最右的位置、局部最小值问题求解

    1. 二分查找 二分查找也是一种在数组中查找数据的算法.它只能查找已经排好序的数据.二分查找通过比较数组中间的数据与目标数据的大小,可以得知目标数据是在数组的左边还是右边.因此,比较一次就可以把查找范 ...

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

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

  4. Java实现二分查找算法

    二分查找(binary search),也称折半搜索,是一种在 有序数组 中 查找某一特定元素 的搜索算法.搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束:如果某一特定元 ...

  5. java,二分查找法,网上查阅

    二分查找又称折半查找,它是一种效率较高的查找方法. 折半查找的算法思想是将数列按有序化(递增或递减)排列,查找过程中采用跳跃式方式查找,即先以有序数列的中点位置为比较对象,如果要找的元素值小于该中点元 ...

  6. Java实现二分查找法

    二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表 ...

  7. 【JAVA】二分查找

    用二分查找来查找数组里出现的元素是一个高效率的查找,但它的局限性是  数组的元素必须有序 二分查找的原理就是:循环找数组的中间元素,如果要找的key比数组的中间元素小,就说明这个key可能在中间值的左 ...

  8. java数组二分查找的简单例题_Java基础-练习 数组元素二分查找(折半查找)

    图解: 二分折半查找使用前提是数组是有序. 题目分析: 通过观察发现,本题目要实现查找指定数值在元素有序的数组中存储的位置(索引),返回该位置(索引). 我们使用数组最中间位置的元素值与要查找的指定数 ...

  9. Java递归算法——二分查找

    import java.lang.reflect.Array; import java.nio.Buffer; import java.util.Arrays; import java.util.Ra ...

最新文章

  1. Django源码分析6:auth认证及登陆保持
  2. CentOS6.8下安装JDK1.8
  3. 一文全览,深度学习时代下,复杂场景下的 OCR 如何实现?
  4. skyline三维模型规格
  5. 网站SEO优化中导入链接有哪些作用?
  6. 深入理解分布式技术 - 负载均衡策略
  7. ubantu18.04使用docker部署mysql5.7及在宿主机登录容器内mysql
  8. 八十九、动态规划系列背包问题之完全背包
  9. mysql在线快速修改密码_MySQL修改密码的几种方式
  10. @staticmethod和@classmethod的作用与区别
  11. 动态计算未知盒子的高度
  12. LINUX SHELL参数连接
  13. OK6410A 开发板 (二) 环境熟悉
  14. Tomcat+Spring奇异事件之Component两次启动
  15. 潜艇空气独立推进系统的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  16. python智能机器人原理_人工智能和Python是什么关系?详细分析!
  17. java葱_Java程序设计_网课答案
  18. 微信小程序登陆验证机制理解及实现
  19. Mysql组合索引使用和用法
  20. 数据治理三大件:元数据、数据标准、数据质量(PPT)

热门文章

  1. 基于网格的空间数据组织
  2. BZOJ-1005-明明的烦恼
  3. Codeforces 1149 题解
  4. NOIP2018 退役记
  5. rhel6上使用udev配置oracle asm,Red Hat Enterprise Linux 6使用udev配置Oracle ASM总结文档
  6. 深拷贝的缺点_JavaScript 深拷贝
  7. overleaf服务端_部署私有在线Latex编辑器:Overleaf/sharelatex,写毕设神器
  8. SourceTree 免登录跳过初始设置
  9. HDU 3068 最长回文
  10. java有参数 无参数方法