You need to enable JavaScript to run this app. 归并排序mergeSort调换条件顺序引发数组越界与结果异常问题
优惠活动
大模型
产品
解决方案
定价
更多

归并排序mergeSort调换条件顺序引发数组越界与结果异常问题

问题核心:Java逻辑或运算符的短路求值规则

Java中||(逻辑或)运算符的求值规则是:只要左侧表达式结果为true,整个表达式就直接返回true,完全不会执行右侧的表达式,这是调换判断顺序后程序出错的根本原因。


两种判断顺序的执行差异

原正常条件的运行逻辑

原条件代码为:

if( j>end || (arr[i]<=arr[j] && i<=mid ))

这个顺序的执行路径没有越界风险:

  1. 首先判断右半段待合并区间的指针j是否越界(也就是右半段的元素已经全部处理完成)
  2. 只要j>end成立,整个条件直接为真,进入取左半段剩余元素的分支,完全不会执行后面涉及数组访问的arr[i]<=arr[j]比较,从根源上避免j越界时还读取arr[j]的问题
  3. 只有当j>end不成立(右半段还没处理完),才会进入右侧括号的判断逻辑,此时j是合法下标,访问arr[j]不会触发越界,最终能正常完成合并,打印出原数组加上排序后数组的完整输出2 4 3 1 1 2 3 4。

调换顺序后的异常原因

修改后的代码为:

if(( arr[i]<=arr[j] && i<=mid) || j>end )

调换||两侧的表达式顺序后,求值逻辑完全颠倒:

  1. 程序会优先计算左侧的arr[i]<=arr[j],此时完全没有提前检查j是否越界
  2. 当右半段处理完成时,j会走到end+1的位置:比如你测试用例的数组长度为4,合法下标最大为3,当end=3时,处理完右半段后j的值就是4。这时候程序还没来得及判断j>end,就直接尝试访问arr[4],自然抛出ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 4,和你遇到的异常栈完全对应。
  3. 由于这个越界异常是在递归合并的过程中触发的,程序直接终止运行,main方法里mergeSort调用完成后的排序结果打印逻辑根本没有执行机会,所以你看到的输出只有最开始打印的原数组内容2 4 3 1。
  4. 哪怕部分场景下没有触发越界,因为判断逻辑的优先级被打乱,原本应该优先处理的“某一段已经遍历完成、直接取另一段剩余元素”的分支,被延后到数组元素比较之后,也会导致合并逻辑错乱,最终输出错误的排序结果。

注意事项

归并排序的合并循环里,凡是涉及数组下标访问的判断,一定要把「指针是否越界」的检查放在最前面,利用短路特性保证越界判断先执行,再做实际的元素值比较,才能从根源上避免下标访问越界的问题。

内容的提问来源于stack exchange,提问作者Ray_Liu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.29 08:15:05