二分查找详解

有序数组,查找target。

重点关注:

public static void main(String[] args) {
    int[] a = {-1, 0, 3, 5, 9, 12, 10};
    int target = 9;
    int left = 0;
    int right = a.length-1;		//right指向数组最后一个元素 
    while (left <= right) {		//left左边<target,right右边大于target;快要结束的时候,如果left和right指向了同一个,那么mid也指向这个地方,由于left和right都没有和target比过,所以需要进入while循环再比一次
        int mid = (left + right) / 2;
        if (a[mid] == target) {
            System.out.println(mid);
            break;
        } else if (a[mid] < target) {
            left = mid + 1;		//left左边<target,因此+1
        } else if (a[mid] > target) {
            right = mid - 1;	//right右边大于target,因此-1,两句话都使得a[mid]和target的比较没有浪费
        }
    }
}
public static void main(String[] args) {
    int[] a = {-1, 0, 3, 5, 9, 12, 10};
    int target = 9;
    int left = 0;
    int right = a.length;	//right指向数组最后一个元素 的 外面第一个
    while (left < right) {	//left是指向 待比较区间的 最左边,right是指向 待比较区间 右边的 外面,不会重叠
        int mid = (left + right) / 2;
        if (a[mid] == target) {
            System.out.println(mid);
            break;
        } else if (a[mid] < target) {
            left = mid + 1;             //mid指向的值已经比target小了
        } else if (a[mid] > target) {
            right = mid;             //mid指向的值已经比target大了,刚好可以做 开区间right值
        }
    }
}

第一种方法更直观。

mid 值,跟除法的向下取整还是向上取整有关系,但是不影响查找,反正都是从待查找区间的中间找。

其他优化: