1、前提:二分查找的前提是需要查找的数组必须是已排序的,我们这里的实现默认为升序

2、原理:将数组分为三部分,依次是中值(所谓的中值就是数组中间位置的那个值)前,中值,中值后;将要查找的值和数组的中值进行比较,若小于中值则在中值前面找,若大于中值则在中值后面找,等于中值时直接返回。然后依次是一个递归过程,将前半部分或者后半部分继续分解为三部分。可能描述得不是很清楚,若是不理解可以去网上找。从描述上就可以看出这个算法适合用递归来实现,可以用递归的都可以用循环来实现。所以我们的实现分为递归和循环两种,可以根据代码来理解算法

3、实现:代码如下

[java] view
plain
copy

  1. package org.cyxl.algorithm.search;
  2. /**
  3. * 二分查找
  4. * @author cyxl
  5. *
  6. */
  7. public class BinarySearch {
  8. private int rCount=0;
  9. private int lCount=0;
  10. /**
  11. * 获取递归的次数
  12. * @return
  13. */
  14. public int getrCount() {
  15. return rCount;
  16. }
  17. /**
  18. * 获取循环的次数
  19. * @return
  20. */
  21. public int getlCount() {
  22. return lCount;
  23. }
  24. /**
  25. * 执行递归二分查找,返回第一次出现该值的位置
  26. * @param sortedData    已排序的数组
  27. * @param start         开始位置
  28. * @param end           结束位置
  29. * @param findValue     需要找的值
  30. * @return              值在数组中的位置,从0开始。找不到返回-1
  31. */
  32. public int searchRecursive(int[] sortedData,int start,int end,int findValue)
  33. {
  34. rCount++;
  35. if(start<=end)
  36. {
  37. //中间位置
  38. int middle=(start+end)>>1;    //相当于(start+end)/2
  39. //中值
  40. int middleValue=sortedData[middle];
  41. if(findValue==middleValue)
  42. {
  43. //等于中值直接返回
  44. return middle;
  45. }
  46. else if(findValue<middleValue)
  47. {
  48. //小于中值时在中值前面找
  49. return searchRecursive(sortedData,start,middle-1,findValue);
  50. }
  51. else
  52. {
  53. //大于中值在中值后面找
  54. return searchRecursive(sortedData,middle+1,end,findValue);
  55. }
  56. }
  57. else
  58. {
  59. //找不到
  60. return -1;
  61. }
  62. }
  63. /**
  64. * 循环二分查找,返回第一次出现该值的位置
  65. * @param sortedData    已排序的数组
  66. * @param findValue     需要找的值
  67. * @return              值在数组中的位置,从0开始。找不到返回-1
  68. */
  69. public int searchLoop(int[] sortedData,int findValue)
  70. {
  71. int start=0;
  72. int end=sortedData.length-1;
  73. while(start<=end)
  74. {
  75. lCount++;
  76. //中间位置
  77. int middle=(start+end)>>1;    //相当于(start+end)/2
  78. //中值
  79. int middleValue=sortedData[middle];
  80. if(findValue==middleValue)
  81. {
  82. //等于中值直接返回
  83. return middle;
  84. }
  85. else if(findValue<middleValue)
  86. {
  87. //小于中值时在中值前面找
  88. end=middle-1;
  89. }
  90. else
  91. {
  92. //大于中值在中值后面找
  93. start=middle+1;
  94. }
  95. }
  96. //找不到
  97. return -1;
  98. }
  99. }

4、测试代码

[java] view
plain
copy

  1. package org.cyxl.algorithm.search.test;
  2. import org.cyxl.algorithm.search.BinarySearch;
  3. import org.junit.Test;
  4. public class BinarySearchTest {
  5. @Test
  6. public void testSearch()
  7. {
  8. BinarySearch bs=new BinarySearch();
  9. int[] sortedData={1,2,3,4,5,6,6,7,8,8,9,10};
  10. int findValue=9;
  11. int length=sortedData.length;
  12. int pos=bs.searchRecursive(sortedData, 0, length-1, findValue);
  13. System.out.println("Recursice:"+findValue+" found in pos "+pos+";count:"+bs.getrCount());
  14. int pos2=bs.searchLoop(sortedData, findValue);
  15. System.out.println("Loop:"+findValue+" found in pos "+pos+";count:"+bs.getlCount());
  16. }
  17. }

5、总结:这种查找方式的使用场合为已排序的数组。可以发现递归和循环的次数是一样的

数据结构和算法设计专题之---二分查找(Java版)的更多相关文章

  1. Java数据结构和算法总结-数组、二分查找

    前言:在平时开发中数组几乎是最基本也是最常用的数据类型,相比链表.二叉树等又简单很多,所以在学习数据和算法时用数组来作为一个起点再合适不过了.本篇博文的所有代码已上传 github ,对应工程的 ar ...

  2. 数据结构和算法:Python实现二分查找(Binary_search)

    在一个列表当中我们可以进行线性查找也可以进行二分查找,即通过不同的方法找到我们想要的数字,线性查找即按照数字从列表里一个一个从左向右查找,找到之后程序停下.而二分查找的效率往往会比线性查找更高. 一. ...

  3. 二分查找-Java版

    /** * * 二分查找算法 * * * * @param srcArray 有序数组 * * @param target 查找元素 * * @return srcArray数组下标,没找到返回-1 ...

  4. [PTA] 数据结构与算法题目集 6-10 二分查找

    Position BinarySearch(List L, ElementType X) { int beg = 1; int end = L->Last; while (beg <= e ...

  5. Leetcode之二分法专题-704. 二分查找(Binary Search)

    Leetcode之二分法专题-704. 二分查找(Binary Search) 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 t ...

  6. 数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解

    数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解 对数组有不了解的可以先看看我的另一篇文章,那篇文章对数组有很多详细的解析,而本篇文章则着重讲动态数组,另一篇文章链接 ...

  7. Python数据结构与算法设计总结篇

    1.Python数据结构篇 数据结构篇主要是阅读[Problem Solving with Python]( http://interactivepython.org/courselib/static ...

  8. Python数据结构与算法设计(总结篇)

    的确,正如偶像Bruce Eckel所说,"Life is short, you need Python"! 如果你正在考虑学Java还是Python的话,那就别想了,选Pytho ...

  9. js基本算法:冒泡排序,二分查找

    知识扩充: 时间复杂度:算法的时间复杂度是一个函数,描述了算法的运行时间.时间复杂度越低,效率越高. 自我理解:一个算法,运行了几次时间复杂度就为多少,如运行了n次,则时间复杂度为O(n). 1.冒泡 ...

随机推荐

  1. Redis端口配置

    redis.host=192.168.200.128redis.port=6379redis.pass=redis.database=0redis.maxIdle=300redis.maxWait=3 ...

  2. 【纪中集训】2019.08.10【省选组】模拟TJ

    前言 一套码农题-- T1 Description 给定一棵\(n(\in[2,10^5])\)个点的树,\(m(≤10^5)\)次询问,每次询问有两个不相同的点,要让所有点走到这两个点之一(走一条边 ...

  3. mysql性能查看 命中率 慢查询

    网上有很多的文章教怎么配置MySQL服务器,但考虑到服务器硬件配置的不同,具体应用的差别,那些文章的做法只能作为初步设置参考,我们需要根据自己的情况进行配置优化,好的做法是MySQL服务器稳定运行了一 ...

  4. 存储-docker存储(12)

    storage driver 和 data volume 是容器存放数据的两种方式 storage driver方式 docker info | grep "Storage Driver&q ...

  5. Branch policies on Azure Repos

    https://docs.microsoft.com/en-us/azure/devops/repos/git/branch-policies-overview?view=azure-devops B ...

  6. thinkphp 连接多个数据库

    config配置文件 //数据库配置信息 'DB_CONFIG' => array( 'DB_TYPE' => 'mysql', // 数据库类型 'DB_HOST' => 'loc ...

  7. 转-C++之string判断字符串是否包含某个子串

    转自:https://blog.csdn.net/zhouxinxin0202/article/details/77862615/ 1.string类函数find C++的string类提供了字符串中 ...

  8. ceph-pg

    版本:mimic https://192.168.1.5:8006/pve-docs/chapter-pveceph.html#pve_ceph_osds As a rule of thumb, fo ...

  9. JS-模拟printf

    function printf(){ var args = [].slice.call(arguments), fmt = args.shift(), args_index = 0; ///%(填充的 ...

  10. Windows 08 R2_NLB负载均衡(图文详解)

    目录 目录 Load Balance 使用NLB来部署Web Farm集群 环境准备 在Win08r2pc1中配置DNS服务 在Win08r2pc1中部署File Service文件服务 在Win08 ...