为何mid--与mid -=1在JavaScript二分查找中返回不同结果?
二分查找中mid--与mid -=1的行为差异分析
核心问题出在后置自增/自减运算符和赋值运算符的返回值逻辑不同:
- 后置
mid--/mid++:先返回变量的原始值,再对变量进行加减操作 mid -=1/mid +=1:先对变量进行加减操作,再返回变量的新值
这两种逻辑直接导致了你的二分查找代码行为不一致,下面用查找目标10的例子拆解差异:
可正常运行的代码(mid--/mid++)
当查找10时:
- 初始
low=0,high=4,计算mid=(0+4)/2=2,array[2]=7 < 10 - 执行
low = mid++:先把mid的原始值2赋值给low,再将mid自增为3 - 下一轮循环:
low=2 < high=4,计算mid=(2+4)/2=3,array[3]=10,匹配成功返回3
无法正常运行的代码(mid -=1/mid +=1)
同样查找10时:
- 初始
low=0,high=4,mid=2,array[2]=7 <10 - 执行
low = mid +=1:先把mid加1变成3,再将新值3赋值给low - 下一轮循环:
low=3 < high=4,计算mid=(3+4)/2=3.5,array[3.5]为undefined,不等于10 - 由于
undefined不大于10,进入else分支执行low = mid +=1,mid变成4.5,low=4.5 - 此时
low=4.5不小于high=4,循环结束,返回[]
额外优化建议
你的代码还有两个可以改进的点:
- 计算
mid时应该用Math.floor((low+high)/2)取整数,避免浮位数组索引的问题 - 循环条件应该用
low <= high,否则当目标是最后一个元素时可能漏查
规范的二分查找写法应该是这样,完全避免运算符返回值的陷阱:
const sourceArray = [1, 5, 7, 10, 15]; const binarySearch = (array, target) => { let low = 0; let high = array.length - 1; while (low <= high) { const mid = Math.floor((low + high) / 2); if (array[mid] === target) { return mid; } else if (array[mid] > target) { high = mid - 1; } else { low = mid + 1; } } return []; }; console.log(binarySearch(sourceArray, 7)); // 2 console.log(binarySearch(sourceArray, 10)); // 3 console.log(binarySearch(sourceArray, 15)); // 4 console.log(binarySearch(sourceArray, 20)); // []
内容的提问来源于stack exchange,提问作者kevin
相关产品推荐
相关产品推荐

