Go语言归并排序正常,JavaScript版本结果偏移1位求排查
归并排序JS版本偏移问题排查与修复
核心错误定位
你的代码问题出在mergeHalves函数的最后一步数组拷贝逻辑上。当前代码始终从数组下标0开始将temp的值覆盖到arr,但实际每次合并的是**leftStart到rightEnd的子区间**,而非整个数组的起始位置,这导致合并后的正确结果没有写入到原数组的对应区间,最终出现排序结果偏移。
排查思路
- 对比结果与预期:观察测试用例的返回结果,发现原数组中靠后的
2未被正确归位,说明合并后的结果没有覆盖到原数组的正确位置。 - 跟踪拷贝过程:检查
mergeHalves最后一步的循环,arr[i] = temp[i]会把temp中临时存储的子区间结果,错误写入到原数组的开头位置,而非当前处理的leftStart起始的子区间,导致前面的正确排序结果被覆盖,后面的目标区间未更新。 - 验证递归分割逻辑:递归分割的
middle计算(Math.floor((start+end)/2))和区间划分(start-middle、middle+1-end)是正确的,和Go版本逻辑一致,排除分割环节的问题。
修复代码
修改mergeHalves函数最后一步的循环,从leftStart开始拷贝temp中的结果到原数组对应位置:
function mergeHalves(arr, leftStart, rightEnd, temp) { const leftEnd = Math.floor((leftStart + rightEnd) / 2); const rightStart = leftEnd + 1; const size = rightEnd - leftStart + 1; let left = leftStart; let right = rightStart; let index = left; while (left <= leftEnd && right <= rightEnd) { if (arr[left] <= arr[right]) { temp[index] = arr[left]; left++; } else { temp[index] = arr[right]; right++; } index++; } while (left <= leftEnd) { temp[index] = arr[left]; index++; left++; } while (right <= rightEnd) { temp[index] = arr[right]; index++; right++; } // 修复:从leftStart开始拷贝到原数组对应区间 for (let i = 0; i < size; i++) { arr[leftStart + i] = temp[leftStart + i]; } }
测试修复后的代码,输入[2, 1, 3, 5, 6, 2, 7]会得到正确的排序结果[1, 2, 2, 3, 5, 6, 7]。
内容的提问来源于stack exchange,提问作者Gianluca Fuoco
相关产品推荐
相关产品推荐

