繁体   English   中英

undefined 从函数返回

[英]undefined is returned from function

我正在研究二进制搜索,这是我想到的第一件事:

 function letsGoBinary(firstArray,array,search){
    const middle = Math.floor(array.length / 2);
    if(search === array[middle]) {
       const rv = firstArray.indexOf(array[middle]);
       return rv
    }else if(search < array[middle]){
       var lowerArray = []
       for(var i = 0; i < middle; i++){
           lowerArray.push(array[i])
       }
       letsGoBinary(firstArray,lowerArray, search)
    }else if(search > array[middle]){
       var forwardArray = []
       for(var i = middle + 1; i < array.length; i++){
           forwardArray.push(array[i]);
       }
       letsGoBinary(firstArray,forwardArray,search)
    }else {
       return -1
    } 
 }

console.log(letsGoBinary([1,4,7,14,16],[1,4,7,14,16], 4))

如果我在第一个 if 语句( search === array[middle] )中添加console.log()并记录它记录确切值的rv ,如果我在 else 语句中not found log 也会发生同样的情况,它会记录但同时日志记录letsGoBinary其值未定义。 我该如何解决?

在进行递归调用的情况下,您需要返回结果。

return letsGoBinary(firstArray,lowerArray, search);

除了您的问题,请检查切片方法的工作原理,循环不是获取数组一部分的必要条件

这段代码也有点无意义,如果你使用

const rv = firstArray.indexOf(array[middle])

那为什么刚开始不使用

const rv = firstArray.indexOf(search)

这行代码使您所有的二分搜索变得毫无意义,因为它会一个一个地搜索元素

有非常简单的解决方案

function letsGoBinary(array, search){
    let start = 0
    let end = array.length - 1

    while (start <= end) {
      const middle = Math.floor((start + end) / 2)   
      if(search === array[middle]) {
         return middle
      } else if (search < array[middle]) {
         end = middle - 1   
      } else {
         start = middle + 1
      }
    }

   return -1
 }

在处理递归函数时,您应该了解基本情况,然后当您想要执行递归调用时,您不仅要再次调用该函数,而且还应该返回该函数作为响应。 例如,如果搜索编号存在于lowerArray 中,则意味着您应该返回letsGoBinary(firstArray,lowerArray, search) 作为答案。

我更新了您的代码,就是这样:注意:查看第 11 行和第 17 行

 function letsGoBinary(firstArray,array,search){ const middle = Math.floor(array.length / 2); if(search === array[middle]) { const rv = firstArray.indexOf(array[middle]); return rv }else if(search < array[middle]){ var lowerArray = [] for(var i = 0; i < middle; i++){ lowerArray.push(array[i]) } return letsGoBinary(firstArray,lowerArray, search) }else if(search > array[middle]){ var forwardArray = [] for(var i = middle + 1; i < array.length; i++){ forwardArray.push(array[i]); } return letsGoBinary(firstArray,forwardArray,search) }else { return -1 } } console.log(letsGoBinary([1,4,7,14,16],[1,4,7,14,16], 4))

发生这种情况是因为在第一次执行 search === array[middle] 后,它完全从letsGoBinary 函数返回,因此您必须添加另一个返回语句,请参阅以下代码片段:

function letsGoBinary(firstArray,array,search){
const middle = Math.floor(array.length / 2);
if(search === array[middle]) {
   const rv = firstArray.indexOf(array[middle]);
   return rv
}else if(search < array[middle]){
   var lowerArray = []
   for(var i = 0; i < middle; i++){
       lowerArray.push(array[i])
   }
   return letsGoBinary(firstArray,lowerArray, search)
}else if(search > array[middle]){
   var forwardArray = []
   for(var i = middle + 1; i < array.length; i++){
       forwardArray.push(array[i]);
       }
       return letsGoBinary(firstArray,forwardArray,search)
    }else {
       return -1
    } 
 }

console.log(letsGoBinary([1,4,7,14,16],[1,4,7,14,16], 4))

Dmitry Reutov 的回答很棒。 如果您更喜欢递归版本,这是一种类似的方法,但使用递归而不是while循环:

 const letsGoBinary = ( sortedArray, value, start = 0, end = sortedArray .length - 1, middle = Math.floor ((end + start) / 2) ) => start > end ? -1 : sortedArray [middle] == value ? middle : sortedArray [middle] < value ? letsGoBinary (sortedArray, value, middle + 1, end) : letsGoBinary (sortedArray, value, start, middle - 1) console .log ( letsGoBinary ([1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233], 34) )

这两种解决方案都只使用一个数组,依靠startendmiddle索引来跟踪当前搜索位置。

此版本默认在第一次调用时startend ,然后在后续搜索中传递它们。 middle在每次调用时计算为startend之间最接近的整数中点。

对于此示例,第一次调用使用012 startend ,使middle 6 ,我们正在测试的值将是sortedArray[6] ,即13 这小于34的搜索值,所以我们再次调用712 ,这使得middle变成9和测试值55 这比34所以我们用78调用, middle 7 ,测试值21 那个小于我们的值,我们又用startend都调用了一个8 ,这给了我们一个middle8和一个测试值34 由于这等于我们的价值,我们返回8 如果我们错过了 - 也许我们正在搜索35 - 那么我们将再次调用9 start8 end ,并返回-1 ,因为start > end 或者,如果我们一直在搜索33 ,我们将有8 start7 end ,结果相同-1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM