二元搜索的替代解决方案一样好吗?

时间:2020-10-22 01:36:17

标签: javascript algorithm search binary-search

对于二进制搜索问题,我提出了以下解决方案:

function binarySearch(arr,numba){
    
    var left = 0
    var right = arr.length - 1
    
    while (left <= right){
        let middle = Math.floor((left+right)/2)
        if (arr[middle] < numba){
            left ++;
            
        }
        else if (numba < arr[middle]){
            right -- ;
            
        }
        else if (numba === arr[middle]){
            return middle
        }
    }
    return -1
}

但建议的解决方案是:

function binarySearc(arr, elem) {
    var start = 0;
    var end = arr.length - 1;
    var middle = Math.floor((start + end) / 2);
    while(arr[middle] !== elem && start <= end) {
        if(elem < arr[middle]){
            end = middle - 1;
        } else {
            start = middle + 1;
        }
        middle = Math.floor((start + end) / 2);
    }
    if(arr[middle] === elem){
        return middle;
    }
    return -1;
}

第二种解决方案是否比我现有的解决方案更好?或者它们本质上是同一回事?

1 个答案:

答案 0 :(得分:2)

是的,第二种解决方案更好。它是唯一实际执行二进制搜索(计算复杂度为O(log n))的二进制文件。请参阅下面的代码片段,以了解使用建议的解决方案需要重新计算middle的次数:

function binarySearc(arr, elem) {
    var start = 0;
    var end = arr.length - 1;
    var middle = Math.floor((start + end) / 2);
    let iterCount = 0;
    while(arr[middle] !== elem && start <= end) {
        iterCount++;
        if(elem < arr[middle]){
            end = middle - 1;
        } else {
            start = middle + 1;
        }
        middle = Math.floor((start + end) / 2);
    }
    console.log('iterCount', iterCount);
    if(arr[middle] === elem){
        return middle;
    }
    return -1;
}

const arr = Array.from({ length: 100 }, (_, i) => i);
binarySearc(arr, 30);

相反,您的解决方案需要按middle次的顺序重新分配O(n)-实际上不是在执行二进制搜索。

function binarySearch(arr,numba){
    
    var left = 0
    var right = arr.length - 1
    
    let iterCount = 0;
    while (left <= right){
        iterCount++;
        let middle = Math.floor((left+right)/2)
        console.log(middle);
        if (arr[middle] < numba){
            left ++;
            
        }
        else if (numba < arr[middle]){
            right -- ;
            
        }
        else if (numba === arr[middle]){
            console.log('iterCount', iterCount);
            return middle
        }
    }
    return -1
}

const arr = Array.from({ length: 100 }, (_, i) => i);
binarySearch(arr, 30);

例如,对于长度为100的数组,您以left为0且right为99开始,然后在循环内的每次迭代中,您可以向左递增1或向右递减真正的二进制搜索将涉及递增或递减以将要搜索的剩余元素减少大约一半-例如,从0-99开始,然后到0-49,然后是24-49,然后是24-36 , 等等。这样,您到达目标(如果存在)的速度比0-99、0-98、0-97等快得多。