《Eloquent JavaScript》习题求助:reverseArrayInPlace循环条件疑问
reverseArrayInPlace 函数逻辑解析与循环终止条件说明
核心疑问:为什么循环终止条件是 Math.floor(array.length / 2)?
这个函数的核心是原地交换数组的首尾对应元素,如果循环遍历整个数组长度,会把已经交换完成的元素再次交换回去,导致数组变回原状态。举两个实际例子:
- 数组长度为奇数(比如长度5):
Math.floor(5/2) = 2,循环执行i=0、1两次,交换索引0↔4、1↔3,中间的索引2(数组最中间的元素)不需要交换,直接保留即可。 - 数组长度为偶数(比如长度4):
Math.floor(4/2) = 2,循环执行i=0、1两次,交换索引0↔3、1↔2,所有元素都完成交换,不会重复操作。
简单说,只需要交换数组前半部分和后半部分的对应元素,循环到数组长度的一半就足够,Math.floor是为了处理奇数长度的情况,舍去小数部分,避免对中间元素做无用操作。
带清晰逻辑注释的函数版本
// 原地反转数组的函数,直接修改原数组而非返回新数组 function reverseArrayInPlace(array) { // 循环遍历数组前半部分,i从0开始,到数组长度的一半时停止 // Math.floor(array.length / 2) 确保只处理需要交换的元素对,避免重复交换 for (let i = 0; i < Math.floor(array.length / 2); i++) { // 暂存当前索引i的元素,用于后续交换 let temp = array[i]; // 将当前位置i的元素替换为对应末尾位置的元素 // array.length - 1 - i 计算当前元素对应的末尾索引(i=0对应最后一个元素,i=1对应倒数第二个) array[i] = array[array.length - 1 - i]; // 将末尾对应位置的元素替换为之前暂存的原i位置元素,完成一对元素的交换 array[array.length - 1 - i] = temp; } // 返回修改后的原数组(原地修改后返回,方便链式调用) return array; }
额外提示
这个函数是原地操作,会直接修改传入的原数组。如果需要保留原数组,应该先复制原数组(比如用[...array]或array.slice())再进行反转操作。
内容的提问来源于stack exchange,提问作者keller
相关产品推荐
相关产品推荐

