二分查找
对一个有序数组查找,涉及递归的方法
二分查找思路
1、首先先确定该数组中间的下标mid=(left+right)/2
2、然后让需要查找的数findVaue和arr[mid]比较
2、1findValue>arr[mid],说明要查找的数在mid的右边,因此需要递归的向右查找。
2、2findValue<arr[mid],说明要查找的数在mid的左边,因从需要递归向左查找。
2、3findValue == arr[mid]说明找到,就返回
什么时候结束递归?
1、找到就结束递归
2、递归完整个数组,仍然没有找到findValur,也需要结束递归,当left>right就需要退出
代码实现
package com.search;
/**
* 使用二分查找的前提是:该数组是有序的
* 此时使用数组是从小到大
* */
public class BinarySearch {
public static void main(String[] args) {
int[] arr={1,8,10,89,100,1234};
int resIndex = binarySearch(arr,0,arr.length-1,134);
System.out.println(resIndex);
}
//二分查找算法
/**
*
* @param arr 数组
* @param left 左边索引
* @param right 右边索引
* @param findValue 查找的值
* @return 如果找到就返回下标,如果没有找到就返回-1
*/
public static int binarySearch(int[] arr,int left,int right,int findValue){
//当left>right时,说明递归了整个数组,但是没有找到
if (left>right){
return -1;
}
int mid = (left+right)/2;
int midVal = arr[mid];
if (findValue > midVal){//向右递归
return binarySearch(arr,mid+1,right,findValue);
}else if (findValue<midVal){//向左递归
return binarySearch(arr,left,mid-1,findValue);
} else {
return mid;
}
}
}
课后思考题
{1,8,10,89,100,100,1234};当一个有序数组中,有多个相同的数值时,如何将所有的数值都查找到,比如这里的100?
package com.search;
import java.util.ArrayList;
import java.util.List;
/**
* 查找数组中某个元素的下标(所有下标)
*/
public class BinarySearch2 {
public static void main(String[] args) {
int[] arr={1,8,10,89,100,100,1234};
List<Integer> resIndexList = binarySearch(arr, 0, arr.length - 1, 100);
System.out.println(resIndexList);
}
/*
思路分析:
1、在找到Mid的值时,不要立即返回
2、向mid索引值左边扫描,将所有满足100的元素加入到ArrayList中
3、向mid索引值右边扫描,将所有满足100的元素的小标,加入到集合ArrayList中
4、将ArrayList返回就可以了
*/
public static List<Integer> binarySearch(int[] arr, int left, int right, int findValue){
//当left>right时,说明递归了整个数组,但是没有找到
if (left>right){
return new ArrayList<Integer>();
}
int mid = (left+right)/2;
int midVal = arr[mid];
if (findValue > midVal){//向右递归
return binarySearch(arr,mid+1,right,findValue);
}else if (findValue<midVal){//向左递归
return binarySearch(arr,left,mid-1,findValue);
} else {
List<Integer> resIndexList = new ArrayList<>();
//向mid索引值左边扫描,将所有满足100的元素加入到ArrayList中
int temp = mid-1;
while (true){
if (temp<0 || arr[temp]!=findValue){//退出
break;
}
//否则,就把temp放入到resIndexList
resIndexList.add(temp);
temp -= 1;//temp左移
}
resIndexList.add(mid);
//向mid索引值右边扫描,将所有满足100的元素的小标,加入到集合ArrayList中
temp = mid +1;
while (true){
if (temp>arr.length-1 || arr[temp]!=findValue){//退出
break;
}
//否则,就把temp放入到resIndexList
resIndexList.add(temp);
temp += 1;//temp左移
}
return resIndexList;
}
}
}