二分查找开闭区间

466 阅读1分钟

边界判断

根据开闭区间的不同,处理的情况不同 二分查找代码大致如下:

let binarySearch = (arr, target) => {
    let begin = 0;
    let end = ???;
    while(???) {
        int mid = begin + (end -begin) / 2;
        if(arr[mid] == target) {}
        else if(arr[mid] > target) {}
        else if(arr[mid] < target) {}
    }
    return ???;
}
复制代码

闭区间,

let search = (arr, target) => {
    let begin = 0;
    let end = arr.length-1; //写成这样,相当于搜索区间为[begin, end],这是一个闭区间
    while(begin <= end) {//重点: 因为闭区间,所以到了begin等于end时,其实区间内还有一个值要判断,
                         //因此只有begin>end的时候才能停止
        let mid = (begin + end) >>> 1;//位运算,无符号右移一位,同Math.floor((begin+end)/2)
        if(arr[mid] == target) {
            return mid;
        }
        else if(arr[mid] > target) {
            end = mid - 1;//因为是闭区间,搜索范围变为[left, mid - 1]
        }
        else if(arr[mid] < target) {
            begin = mid + 1; //搜索范围变成[mid + 1, end]
        }
    }
    return -1;
}
复制代码

开区间:

let search = (arr, target) => {
    let begin = 0;
    let end = arr.length; //写成这样,相当于搜索区间为[begin, end),这是一个前闭后开的区间
    while(begin < end) {//重点:
                       //因为前闭后开的区间,所以到了begin等于end时,其实区间内已经没有值了,直接停止
        let mid = (begin + end) >>> 1;
        if(arr[mid] == target) {
            return mid;
        }
        else if(arr[mid] > target) {
            end = mid;//因为是闭区间,搜索范围变为[left, mid - 1]
        }
        else if(arr[mid] < target) {
            begin = mid + 1; //搜索范围变成[mid + 1, end]
        }
    }
    return -1;
}