无限循环与JavaScript中的二进制搜索实现

无限循环与JavaScript中的二进制搜索实现,javascript,binary-search,Javascript,Binary Search,这是我关于堆栈溢出的第一个问题,请耐心听我说。 我写了这个binarySearch函数,由于某种原因它挂起了——我假设是因为一个无限循环。有人能找到我代码的错误吗 let binarySearch = (array, value) => { let target = value, start = 0, end = array.length - 1, middle = Math.floor( (end + start)/2 ) while (start

这是我关于堆栈溢出的第一个问题,请耐心听我说。 我写了这个binarySearch函数,由于某种原因它挂起了——我假设是因为一个无限循环。有人能找到我代码的错误吗

let binarySearch = (array, value) => {
 let target = value,
     start = 0,
     end = array.length - 1,
     middle = Math.floor( (end + start)/2 )

  while (start <= end){

    if ( array[middle] === target ){
      return true
    }else if (array[middle] < target){
      start = middle + 1
    }else if (array[middle] > target){
      end = middle - 1
    }    
  }
 return false
}
let binarySearch=(数组,值)=>{
让目标=价值,
开始=0,
end=array.length-1,
中间=数学楼层((结束+开始)/2)
while(启动目标){
结束=中间-1
}    
}
返回错误
}

最明显的错误是,您需要将
middle
计算为循环内的第一个操作,而不是循环外的第一个操作

没有这个更改,您总是在检查函数第一次调用时哪个元素是“中间”的,并且永远不要分区搜索空间


有了这个修复,我的测试表明代码可以按要求工作,尽管在注释中建议您应该返回找到的元素的索引,不仅仅是一个表示元素是否被找到的标志。

最明显的错误是,您需要将
middle
计算为循环内的第一个操作,而不是循环外的第一个操作

如果没有这种更改,您总是在第一次调用函数时检查哪个元素是“中间”的,而从不划分搜索空间


有了这个修正,我的测试表明代码按要求工作,尽管在注释中建议您应该返回找到的元素的索引,而不仅仅是一个表示元素是否被找到的标志。

由于所示的实现是迭代二进制搜索,所以出现了无限循环,但是,
middle
值不会像其他人提到的那样在每次迭代时重新计算。因此,
middle
变量在第一次迭代之后永远不会更改

下面是一个实现,它返回
,或者
,如果找不到值

function binarySearch(array, value) {
  let middle, start = 0,
    end = array.length - 1;

  while (start <= end) {
    middle = Math.floor((start + end) / 2);

    if (array[middle] > value) {
      end = middle - 1;
    } else if (array[middle] < value) {
      start = middle + 1;
    } else {
      return middle;
    }
  }
  return null;
}
函数二进制搜索(数组,值){
让中间,开始=0,
end=array.length-1;
while(起始值){
结束=中间-1;
}else if(数组[中间]<值){
开始=中间+1;
}否则{
返回中间;
}
}
返回null;
}

出现无限循环是因为所示的实现是迭代二进制搜索,但不会像其他人提到的那样,在每次迭代时重新计算中间的值。因此,
middle
变量在第一次迭代之后永远不会更改

下面是一个实现,它返回
,或者
,如果找不到值

function binarySearch(array, value) {
  let middle, start = 0,
    end = array.length - 1;

  while (start <= end) {
    middle = Math.floor((start + end) / 2);

    if (array[middle] > value) {
      end = middle - 1;
    } else if (array[middle] < value) {
      start = middle + 1;
    } else {
      return middle;
    }
  }
  return null;
}
函数二进制搜索(数组,值){
让中间,开始=0,
end=array.length-1;
while(起始值){
结束=中间-1;
}else if(数组[中间]<值){
开始=中间+1;
}否则{
返回中间;
}
}
返回null;
}

不管有什么缺陷,二进制搜索算法都应该返回找到的项的索引(如果没有找到,则返回
未定义的
或类似的索引),而不仅仅是一个布尔值来表示是否找到了值。您是否考虑过记录
开始
中间
的值,和
end
查看可能发生的情况?我建议在while循环的开头添加警报,以检查每次传递的值。您可能会很容易发现这个问题。不管有什么错误,二进制搜索算法都应该返回找到的项的索引(如果没有找到,则返回
未定义的
或类似的索引),而不仅仅是一个布尔值来表示是否找到了该值。您是否考虑过记录
开始
中间
的值,和
end
查看可能发生的情况?我建议在while循环的开头添加警报,以检查每次传递的值。你可能会很容易发现这个问题。啊,我明白了。谢谢你的提示。另外,如果您想使用二进制搜索来查看元素是否存在,该怎么办?你能详细解释一下为什么它总是索引吗?@mega0319因为通过二进制搜索,你可以“免费”得到索引,此时存在性测试只是对
索引<0
索引!==未定义
,具体取决于您发出“未找到”信号的方式。无论如何,把这个单独的测试包装成一个它自己的函数,但是如果二进制搜索告诉你索引,为什么要丢弃这些信息呢?啊,我明白了。谢谢你的提示。另外,如果您想使用二进制搜索来查看元素是否存在,该怎么办?你能详细解释一下为什么它总是索引吗?@mega0319因为通过二进制搜索,你可以“免费”得到索引,此时存在性测试只是对
索引<0
索引!==未定义
,具体取决于您发出“未找到”信号的方式。无论如何,把这个单独的测试包装成它自己的函数,但是如果二进制搜索告诉你索引,为什么要把这些信息扔掉呢?很明显,但我没有看到它!谢谢如此明显,但我没有看到它!谢谢