题目
用二分法查找有序数组中某一个数字,找到这个数字后返回该数字的下标
思路
先将这组数据保存到一个数组中,再设定三个变量,i用来表示数组第一个位置的下标,j用来表示数组最后一个位置的下标,mid用来表示i和j中间位置的下标。
将mid下标所对应的数字与要找的数字n作比较,如果大于n,就把j移到mid-1的位置,如果小于n,就把i移到mid+1的位置,然后再更新mid的值。
array[mid]>n的情况:
array[mid]<n的情况:
那么问题来了,为什么是把i移到mid+1的位置而不是移到mid的位置呢?
因为我们循环的条件是array[mid]!=n,相当于我们每一次都会将array[mid]与n进行比较,当array[mid]==n时就会返回mid的值,如果把i移到mid的位置,就相当于每次都把mid的位置重新遍历一遍,所以我们不采用这种方法。
我们在进行数字比较的前提是i<=j的情况,如果i>j,那就说明在这个数组中没有找到这个数字,就返回-1。
值得注意的一个点是在这里求mid的方法不是用(i+j)/2,而是用(j-i)/2+i,因为我们是在数组里面计算,数组的长度是有上限的,如果i+j的值超出它的上限,他还是会先去找(i+j)这个下标的位置,到时候很可能得不到我们想要的结果。
代码实现
import java.util.Scanner;
public class BinarySearch {
public static int search(int[] array,int n) {
int i = 0;
int j = array.length - 1;
int mid = (j-i)/2+i;
while (array[mid] != n) {
if(j>=i){
if (array[mid] < n) {
i = mid+1;//n>array[mid]说明要查找的数据在后半段,将i移到mid后面的位置
}
if(array[mid]>n){
j = mid-1;
}
mid = (i+j)/2;
}else{
return -1;//当i>j的时候,说明数组中不存在这个数据,返回-1
}
}
return mid;//当array[mid]==n时,返回mid的值
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[] array = new int[scanner.nextInt()];
for(int i = 0;i<array.length;i++){
array[i] = scanner.nextInt();//将输入的数据存到数组中
}
int n = scanner.nextInt();
System.out.println(search(array, n));
}
}
运行结果