注意:
二分查找法只能用于有序的数组
思路分析:
1、首先确定该数组中间的下标 mid=(left+right)/2
2、然后让需要查找的数findVal和arr[mid]进行比较
(1)如果findVal>arr[mid],则向数的右边进行递归查找
(2)如果findVal<arr[mid],则向数的左边进行递归查找
(3)findVal==arr[mid]就返回
什么时候结束递归?
(1)找到就结束
(2)当left>right
代码实现:
public class halfSearch {
public static void main(String[] args) {
// TODO 自动生成的方法存根
//定义一个测试数组
int[] arr= {1,8,10,66,89,120,145,1000,1024};
//需要寻找的数组
int findVal=1024;
System.out.println(HalfSearch(arr, findVal, 0, arr.length-1));
}
public static int HalfSearch(int[] arr,int findVal,int left,int right) {
int mid=(left+right)/2; //中间的数
if(left<=right) { //结束循环条件
if(findVal>arr[mid]) { //向右进行递归查找
return HalfSearch(arr, findVal, mid+1, right);
}else if(findVal<arr[mid]) { //向左进行递归查找
return HalfSearch(arr, findVal, left, mid);
}else { //找到了,返回下标
return mid;
}
}else {
return -1;
}
}
}
改进:
实现查找一个数组中有多个findVal,得到所有的下标
思路:
(1)在找到mid索引后,不要马上返回
(2)向mid索引值得左边扫描,找到所有满足findVal的元素下标,加入到集合ArrayList中
(3)向mid索引值得右边扫描,找到所有满足findVal的元素下标,加入到集合ArrayList中
(4)将ArrayList返回
代码实现:
public static List<Integer> HalfSearch2(int[] arr,int findVal,int left,int right) {
int mid=(left+right)/2;
if(left<=right) {
if(findVal>arr[mid]) {
return HalfSearch2(arr, findVal, mid+1, right);
}else if(findVal<arr[mid]) {
return HalfSearch2(arr, findVal, left, mid+1);
}else {
List<Integer> indexList=new ArrayList<>();
//向左边进行查找
int tempLeft=mid-1;
while(true) {
if(tempLeft<0||arr[tempLeft]!=findVal) {
break;
}
indexList.add(tempLeft);
tempLeft--; //左移
}
indexList.add(mid);
//向右边进行递归查找
int tempRight=mid+1;
while(true) {
if(tempRight>arr.length-1||arr[tempRight]!=findVal) {
break;
}
indexList.add(tempRight);
tempRight++; //右移
}
return indexList;
}
}else {
return new ArrayList<Integer>();
}
}