二分查找需要的是一个有序的数组,对该有序的数组进行二分查找。
基本思路:
1.先定义一个有序的数组
2.确定该数组的中间下标mid = (left + right)/2
3.findVal > arr[mid] 说明要查找的数在mid的右边,因此需要递归向右查找
4.findVal < arr[mid] 说明要查找的数在mid的左边,因此需要递归向左查找
5.findVal = arr[mid] 说明找到,就返回这个值
结束递归的标识:
1)找到就结束递归
2)递归完整个数组,仍然没有找到findVal,也需要结束递归。即left > right 就退出。
Java代码实现:
import java.util.Scanner;
public class BinarySearch {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 先定义一个没有顺序的数组
System.out.println("请输入数组的大小:");
Scanner input = new Scanner(System.in);
int a = input.nextInt();
int[] arr = new int[a];
for (int i = 0; i < arr.length; i++) {
System.out.println("请输入数组的第" + (i + 1) + "个值:");
int s = input.nextInt();
arr[i] = s;
}
System.out.println("请输入要查找的值:");
int value = input.nextInt();
int resIndex = binarySearch(arr, 0, arr.length-1, value);
System.out.println("resIndex的位置:" + resIndex+"值为:"+arr[resIndex]);
}
//编写二分查找方法
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;
}
}
}
可以对上述查找方法进行一点改进,如果在查询的数组中有多个符合查询条件的值,则将这些值所在的位置存放到一个list集合中,将list集合返回。
实现代码如下:
/**
* 查找所有符合要求的数据
* 1.在找到mid索引值,不要马上返回
* 2.向mid 索引值的左边扫描,将所有满足条件的元素下标加入到list集合中
* 3.向mid索引值的右边扫描,将所有满足条件的元素下标加入到list集合中
* 4.将list集合返回
*/
public static ArrayList binarySearch2(int[] arr,int left,int right,int findVal) {
//当left > right 时,说明递归整个数组,但是没有找到
if(left > right) {
return new ArrayList();
}
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 {
ArrayList list = new ArrayList();
//向mid索引值的左边扫描,将所有满足条件的元素加入集合中
int temp = mid - 1;
while(true) {
if(temp < 0 || arr[temp] != findVal) {
break;
}
//否则就代表还有符合条件的元素,将其加入到集合中
list.add(temp);
temp -= 1;//temp左移
}
list.add(mid);
//向mid索引值的右边扫描,将所有满足条件的元素加入集合中
temp = mid + 1;
while(true) {
if(temp > arr.length-1 || arr[temp] != findVal) {
break;
}
//否则就代表还有符合条件的元素,将其加入到集合中
list.add(temp);
temp += 1;//temp右移
}
return list;
}
}