二分查找(Java递归版)

简介: 二分查找(Java递归版)

二分查找的原理:(所查找的数组必须是有序的)


查找过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则查找过程结束;

如果查找元素大于(小于)中间元素,则在数组大于(小于)中间元素的那一半区间中查找,而且跟开始一样从中间元素开始比较。直到在某一步判断时数组为空数组,说明没有找到该元素


二分查找的思路:


先找到有序数组的中间位置mid = (left+right)/2,然后用有序数组找到中间位置的元素,即arr[mid]与目标元素findVal进行比较,若arr[mid]大于findVal,即说明目标元素findVal在arr[mid]的左边,我们就将索引right左移为(mid-1),若arr[mid]小于findVal,即说明目标元素findVal在arr[mid]的右边,我们就将索引left右移为(mid+1),不断的如此折半查找,直到满足条件findVal==arr[mid]为止,说明查找到此元素的索引mid。


代码实现:


public static int binarySearch(int[] arr, int left, int right, int findVal) {
  // 当left > right时,说明递归整个数组,但是没有找到
  if (left > right) {
    return -1;
  }
  int mid = (left + right) / 2;
  int midVal = arr[mid];
  if (findVal > midVal) {// 向右递归
    return binarySearch(arr, mid + 1, right, findVal);
  } else if (findVal < midVal) {
    return binarySearch(arr, left, mid - 1, findVal);// 向左递归
  } else {
    return mid;
  }
  }


经过测试后,可知上诉述的二分查找只能找到目标元素的一个索引,若目标元素在数组有多个,则不能将所有的目标索引找出来。由此我们可以继续对这个二分查找进行完善。


完善思路:


将binarySearch()方法的返回值改为List集合,在else语句中进行对第一次找到的mid,即第一次找到的findval的索引的左右进行顺序查找,若找到则添加到List集合中。下面是博主的实现代码,可供大家参考。若有更好的实现方式,也请大佬们指教。


public static List<Integer> binarySearch2(int[] arr, int left, int right, int findVal) {
  // 当 left > right 时,说明递归整个数组,但是没有找到
  if (left > right) {
    return new ArrayList<Integer>();
  }
  int mid = (left + right) / 2;
  int midVal = arr[mid];
  if (findVal > midVal) { // 向 右递归
    return binarySearch2(arr, mid + 1, right, findVal);
  } else if (findVal < midVal) { // 向左递归
    return binarySearch2(arr, left, mid - 1, findVal);
  } else {
    List<Integer> resIndexlist = new ArrayList<Integer>();
    // 向 mid 索引值的左边扫描,将所有满足 findVal, 的元素的下标,加入到集合 ArrayList
    int temp = mid - 1;
    while (true) {
    if (temp < 0 || arr[temp] != findVal) {// 退出
      break;
    }
    // 否则,就 temp 放入到 resIndexlist
    resIndexlist.add(temp);
    temp -= 1; // temp 左移
    }
    resIndexlist.add(mid); //
    // 向 mid 索引值的右边扫描,将所有满足 findVal, 的元素的下标,加入到集合 ArrayList
    temp = mid + 1;
    while (true) {
    if (temp > arr.length - 1 || arr[temp] != findVal) {// 退出
      break;
    }
    // 否则,就 temp 放入到 resIndexlist
    resIndexlist.add(temp);
    temp += 1; // temp 右移
    }
    return resIndexlist;
  }
  }
目录
相关文章
|
1月前
|
Java
在 Java 中实现二分查找法
【10月更文挑战第9天】
25 1
|
2月前
|
Java
java基础(11)函数重载以及函数递归求和
Java支持函数重载,即在同一个类中可以声明多个同名方法,只要它们的参数类型和个数不同。函数重载与修饰符、返回值无关,但与参数的类型、个数、顺序有关。此外,文中还展示了如何使用递归方法`sum`来计算两个数之间的和,递归的终止条件是当第一个参数大于第二个参数时。
32 1
java基础(11)函数重载以及函数递归求和
|
1月前
|
算法 Java
java冒泡排序与二分查找(详解)
java冒泡排序与二分查找(详解)
33 4
|
4月前
|
算法 Java
java使用递归及迭代方式实现前序遍历 中序遍历 后序遍历 以及实现层序遍历
java使用递归及迭代方式实现前序遍历 中序遍历 后序遍历 以及实现层序遍历
86 7
|
4月前
|
算法 Java
Java 使用二分查找快速定位元素位置
Java 使用二分查找快速定位元素位置
23 0
|
5月前
|
Java
java实现斐波那契数列(递归、迭代、流)
java实现斐波那契数列(递归、迭代、流)
|
5月前
|
存储 Java
Java基础手册(标识符 关键字 字面值 变量 数据类型 字符编码 运算符 控制语句 方法及方法重载和递归 面向对象与面向过程)
Java基础手册(标识符 关键字 字面值 变量 数据类型 字符编码 运算符 控制语句 方法及方法重载和递归 面向对象与面向过程)
39 0
|
5月前
|
Java 大数据 程序员
老程序员分享:java递归
老程序员分享:java递归
28 0
|
5月前
|
Java
二分查找-非递归(java)
二分查找-非递归(java)
|
5月前
|
Java
二分查找-递归(java)
二分查找-递归(java)