【问题标题】:I'm trying to write a simple binary search and I can't get it to return the position, it finds it but won't return it我正在尝试编写一个简单的二进制搜索,但我无法让它返回位置,它找到但不会返回它
【发布时间】:2020-07-07 01:37:32
【问题描述】:

我正在尝试编写一个简单的二进制搜索函数来查找数组中的值并返回它的位置,如果不存在则返回 -1。通过控制台日志,我可以看到它在内部工作,但没有返回我想要的。它总是返回 undefined...

function binarySearch(arr, q) {
    // set left right middle
    let left = 0,
        right = arr.length - 1,
        middle = Math.floor(arr.length / 2);
    // check if the middle is q
    if (arr[middle] === q) {
        return middle;
    }
    console.log(checkMiddle(left, right, middle));

    let answer = checkMiddle(left, right, middle);

    function checkMiddle(l, r, m) {
        console.log(r - l);
        if (r - l === 1) {
            console.log('not found');
            return -1;
        }
        if (arr[m] === q) {
            // if yes return middle
            console.log('found');
            console.log(m);
            return m;
        }

        //if not find if q is > or < middle
        if (q > arr[m]) {
            // if > move left to middle
            l = m;

            //move middle to new middle
        } else {
            //if < move right to middle
            r = m;
        }
        m = Math.floor((r + l) / 2);
        //search again
        console.log(l, r, m);

        checkMiddle(l, r, m);
    }

    return answer;
}

let arr = [1, 2, 3, 4, 5, 6, 7, 55, 192, 5000, 666666, 8888888, 1055556565456],
    q = 10;
console.log(binarySearch(arr, q));

【问题讨论】:

  • 您的 checkMiddle 方法没有返回任何内容,因此答案未定义
  • @HarmandeepSinghKalsi 但是在第 23 行我有 console.log(m);然后在第 24 行我有return m; 23 将 console.log 我想要返回的内容,但 24 没有返回
  • 由于你使用的是递归,return 也可以意味着你正在返回到之前的调用堆栈
  • @HarmandeepSinghKalsi 好的,我该如何解决?我很迷茫
  • 请在这里查看一次geeksforgeeks.org/…

标签: javascript binary-search


【解决方案1】:

它返回 undefined 因为您没有从函数中返回任何内容,也没有将答案存储在变量中。

在递归函数中使用 return 只会返回到前一个调用堆栈。

定义一个全局变量,让你的递归函数在每次调用时将答案存储在其中,这样你就可以在函数完成后返回它。

下面的修改代码。

function binarySearch(arr, q) {
    // set left right middle
    let left = 0,
        right = arr.length - 1,
        middle = Math.floor(arr.length / 2);
    // check if the middle is q
    if (arr[middle] === q) {
        return middle;
    }
    //console.log(checkMiddle(left, right, middle));

    let answer = 0; // global variable which is modified by the checkMiddle function
    checkMiddle(left, right, middle);
    
    function checkMiddle(l, r, m) {
        console.log(r - l);
        if (r - l === 1) {
            console.log('not found');
            answer = -1;
            return;
        }
        if (arr[m] === q) {
            // if yes return middle
            console.log('found');
            console.log(m);
            answer = m;
            return;
        }

        //if not find if q is > or < middle
        if (q > arr[m]) {
            // if > move left to middle
            l = m;

            //move middle to new middle
        } else {
            //if < move right to middle
            r = m;
        }
        m = Math.floor((r + l) / 2);
        //search again
        console.log(l, r, m);

        checkMiddle(l, r, m);
    }
    console.log("answer : "+answer);
    return answer;
}

let arr = [1, 2, 3, 4, 5, 6, 7, 55, 192, 5000, 666666, 8888888, 1055556565456],
    q = 10;
console.log(binarySearch(arr, q));

【讨论】:

  • 非常感谢。我什至需要在这里使用递归吗?
  • 不,您也可以使用迭代方法@Rick。请检查此geeksforgeeks.org/binary-search-in-javascript
  • 对于二分搜索,不使用递归会更有效,因为它不需要。我想你只是用这个作为学习递归的例子。
【解决方案2】:

我认为这是一种更简单的方法。


    let arr = [1, 2, 3, 4, 5, 6, 7, 55, 192, 5000, 666666, 8888888, 1055556565456];


    function binarySearch(arr, k, s, e){
        
      s = s || 0;
      e = e || arr.length;
      
      m = s + Math.floor((e - s) / 2);
        
        if (arr[m] === k)
            return m;
        
        if (k > arr[m]){
            return (m+1 < e)?binarySearch(arr, k, m+1, e):-1;
        }else if (m-1 >= s){
            return binarySearch(arr, k, s, m-1);
        }
        
        return -1;
    }


    console.log('answer: '+binarySearch(arr, 3));   //  2
    console.log('answer: '+binarySearch(arr, 10));  // -1
    console.log('answer: '+binarySearch(arr, 55));  //  7

这是一个尝试在迭代的每个步骤中查找“40”的示例。 (其中 V 是被检查数组中的值)

S = 0, E = 13, V = 7  (40 is higher than 7)
Search upper half...
S = 7, E = 13, V = 666666 (40 is lower than 666666)
Search lower half...
S = 7, E = 9, V = 192 (40 is lower than 192)
Search lower half...
S = 7, E = 7, V = 55 (40 is lower than 55)
Not found.

【讨论】:

  • 这看起来不错,但是当第一次调用时,如果 k 为 0 或 arr.length-1,我看不出它在哪里。或者如果碰巧有 s 或 e 是 q 的情况。
  • 不管 K 是什么,这就是要搜索的值。 (我知道的变量名很差) S 和 E 是数组的索引。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-05
  • 1970-01-01
  • 2019-05-26
  • 2018-09-25
  • 1970-01-01
相关资源
最近更新 更多