用二分查找实现findIndex

1,029 阅读1分钟

二分查找也叫折半查找,是一种在相当大的数据规模下常用的高效率的查找方法。每次搜索范围减少一半,时间复杂度为 log n,不过在使用前数组必须排好顺序。

1.普通写法

function findIndex(arr, val, left = 0, right = arr.length - 1) {
    if(left > right) return -1
    let center = Math.floor((left + right) / 2)
    // 防止溢出的写法: center = (left + right) >>> 1
    if(arr[center] === val) {
        return center
    }else if(arr[center] > val) {
        right = center - 1
    }else {
        left = center + 1
    }
    return findIndex(arr, val, left, right)
}

2.查找左边界

function findIndexLeft(arr, val, left = 0, right = arr.length - 1) {
    if(left > right) return -1
    let center = Math.floor((left + right) / 2)
    if(arr[center] === val) {
        while(arr[center - 1] === val) {
            center--
        }
        return center
        /* 另一种写法
        if(arr[center - 1] === val) {
            right =  center -1
        }else {
            return center
        }
        */
    }else if(arr[center] > val) {
        right = center - 1
    }else {
        left = center + 1
    }
    return findIndexLeft(arr, val, left, right)
}

3.查找右边界

function findIndexRight(arr, val, left = 0, right = arr.length - 1) {
    if(left > right) return -1
    let center = Math.floor((left + right) / 2)
    if(arr[center] === val) {
        while(arr[center + 1] === val) {
            center++
        }
        return center
        /* 另一种写法
        if(arr[center + 1] === val) {
            left = center + 1
        }else {
            return center
        }
        */
    }else if(arr[center] > val) {
        right = center - 1
    }else {
        left = center + 1
    }
    return findIndexRight(arr, val, left, right)
}