毕业生求职必会算法手把手教你二分法查找

开发 前端 算法
当数组或者集合中存放的元素数量非常多的时候,想要跟踪具体某个元素的位置或者是否存在,常规方式是循环每一个元素直到找到要查找的元素为止。这样的查找方式效率非常低下,这个时候需要使用二分法来实现,提高查找效率。

 1、二分法查找的背景

当数组或者集合中存放的元素数量非常多的时候,想要跟踪具体某个元素的位置或者是否存在,常规方式是循环每一个元素直到找到要查找的元素为止。这样的查找方式效率非常低下,这个时候需要使用二分法来实现,提高查找效率。

2、二分法查找的介绍

二分法查找(折半查找),找指定数值所在的位置

百度百科是这样介绍二分法查找的:


3、二分法查找的算法思想

假设数组是按升序排序的,对于给定的目标值aim,从数组的中间位置开始查找:1.若查找数据与中间元素值正好相等,则返回中间元素值的索引;2.若查找数值比中间值小,则以整个查找范围的前半部分作为新的查找范围;3.若查找数值比中间值大,则以整个查找范围的后半部分作为新的查找范围;注:查找成功返回索引,失败返回-1

4、代码实现

4.1 利用循环的方式实现二分法查找

  1. public class BinarySearch { 
  2.     public static void main(String[] args) { 
  3.         // 生成一个随机数组 
  4.         int[] array = suiji(); 
  5.         // 对随机数组排序 
  6.         Arrays.sort(array); 
  7.         System.out.println("产生的随机数组为: " + Arrays.toString(array)); 
  8.  
  9.         System.out.println("要进行查找的值: "); 
  10.         Scanner input = new Scanner(System.in); 
  11.         // 进行查找的目标值 
  12.         int aim = input.nextInt(); 
  13.  
  14.         // 使用二分法查找 
  15.         int index = binarySearch(array, aim); 
  16.         System.out.println("查找的值的索引位置: " + index); 
  17.  
  18.     } 
  19.  
  20.     /** 
  21.      * 生成一个随机数组 
  22.      *  
  23.      * @return 返回值,返回一个随机数组 
  24.      */ 
  25.     private static int[] suiji() { 
  26.         // random.nextInt(n)+m  返回m到m+n-1之间的随机数 
  27.         int n = new Random().nextInt(6) + 5; 
  28.         int[] array = new int[n]; 
  29.         // 循环遍历为数组赋值 
  30.         for (int i = 0; i < array.length; i++) { 
  31.             array[i] = new Random().nextInt(100); 
  32.         } 
  33.         return array; 
  34.     } 
  35.  
  36.     /** 
  37.      * 二分法查找  ---循环的方式实现 
  38.      *  
  39.      * @param array 要查找的数组 
  40.      * @param aim 要查找的值 
  41.      * @return 返回值,成功返回索引,失败返回-1 
  42.      */ 
  43.     private static int binarySearch(int[] array, int aim) { 
  44.         // 数组最小索引值 
  45.         int left = 0; 
  46.         // 数组最大索引值 
  47.         int right = array.length - 1; 
  48.         int mid; 
  49.         while (left <= right) { 
  50.             mid = (left + right) / 2; 
  51.             // 若查找数值比中间值小,则以整个查找范围的前半部分作为新的查找范围 
  52.             if (aim < array[mid]) { 
  53.                 right = mid - 1; 
  54.                 // 若查找数值比中间值大,则以整个查找范围的后半部分作为新的查找范围 
  55.             } else if (aim > array[mid]) { 
  56.                 left = mid + 1; 
  57.                 // 若查找数据与中间元素值正好相等,则放回中间元素值的索引 
  58.             } else { 
  59.                 return mid; 
  60.             } 
  61.         } 
  62.         return -1; 
  63.     } 

代码执行结果:

  1. 产生的随机数组为: [16, 33, 40, 46, 57, 63, 65, 71, 85] 
  2. 要进行查找的值:  
  3. 46 
  4. 查找的值的索引位置: 3 

若输入的值找不到,则返回-1

  1. 产生的随机数组为: [28, 41, 47, 56, 70, 81, 85, 88, 95] 
  2. 要进行查找的值:  
  3. 66 
  4. 查找的值的索引位置: -1 

4.2 利用递归的方式实现二分法查找

  1. public class BinarySearch2 { 
  2.     public static void main(String[] args) { 
  3.         // 生成一个随机数组 
  4.         int[] array = suiji(); 
  5.         // 对随机数组排序 
  6.         Arrays.sort(array); 
  7.         System.out.println("产生的随机数组为: " + Arrays.toString(array)); 
  8.  
  9.         System.out.println("要进行查找的值: "); 
  10.         Scanner input = new Scanner(System.in); 
  11.         // 进行查找的目标值 
  12.         int aim = input.nextInt(); 
  13.  
  14.         // 使用二分法查找 
  15.         int index = binarySearch(array, aim, 0, array.length - 1); 
  16.         System.out.println("查找的值的索引位置: " + index); 
  17.     } 
  18.  
  19.     /** 
  20.      * 生成一个随机数组 
  21.      * 
  22.      * @return 返回值,返回一个随机数组 
  23.      */ 
  24.     private static int[] suiji() { 
  25.         // Random.nextInt(n)+m  返回m到m+n-1之间的随机数 
  26.         int n = new Random().nextInt(6) + 5; 
  27.         int[] array = new int[n]; 
  28.         // 循环遍历为数组赋值 
  29.         for (int i = 0; i < array.length; i++) { 
  30.             array[i] = new Random().nextInt(100); 
  31.         } 
  32.         return array; 
  33.     } 
  34.  
  35.     /** 
  36.      * 二分法查找 ---递归的方式 
  37.      * 
  38.      * @param array 要查找的数组 
  39.      * @param aim   要查找的值 
  40.      * @param left  左边最小值 
  41.      * @param right 右边最大值 
  42.      * @return 返回值,成功返回索引,失败返回-1 
  43.      */ 
  44.     private static int binarySearch(int[] array, int aim, int leftint right) { 
  45.         if (aim < array[left] || aim > array[right]) { 
  46.             return -1; 
  47.         } 
  48.         // 找中间值 
  49.         int mid = (left + right) / 2; 
  50.         if (array[mid] == aim) { 
  51.             return mid; 
  52.         } else if (array[mid] > aim) { 
  53.             //如果中间值大于要找的值则从左边一半继续递归 
  54.             return binarySearch(array, aim, left, mid - 1); 
  55.         } else { 
  56.             //如果中间值小于要找的值则从右边一半继续递归 
  57.             return binarySearch(array, aim, mid + 1, array.length-1); 
  58.         } 
  59.     } 

递归相较于循环,代码比较简洁,但是时间和空间消耗比较大,效率低。在实际的学习与工作中,根据情况选择使用。

 

责任编辑:姜华 来源: 程序猿编程
相关推荐

2023-12-27 23:30:50

2021-12-26 00:10:39

二分法排查版本

2018-06-15 14:26:42

2011-03-24 14:15:27

双TOP二分法分页

2021-12-11 20:20:19

Python算法线性

2021-10-19 09:59:25

二分法排序数组

2012-12-29 14:29:12

应届毕业生求职

2022-04-13 07:31:20

CAP定理分布式数据库

2010-05-25 10:44:42

毕业生求职陷阱

2010-05-27 10:10:07

职场经验

2021-07-14 09:00:00

JavaFX开发应用

2017-12-19 15:54:28

工作流Git二分法

2012-12-29 16:20:55

应届毕业生求职

2011-01-10 14:41:26

2011-05-03 15:59:00

黑盒打印机

2023-04-26 12:46:43

DockerSpringKubernetes

2022-03-14 14:47:21

HarmonyOS操作系统鸿蒙

2022-01-08 20:04:20

拦截系统调用

2022-07-27 08:16:22

搜索引擎Lucene

2022-12-07 08:42:35

点赞
收藏

51CTO技术栈公众号