为何Kotlin原排序代码无数组越界错误,修改后反而触发报错?
问题1:var index = elements.size - 2中减去2的作用是什么?
这个排序函数的调用时机是每次往数组末尾新增元素之后,本质是插入排序的单趟上浮逻辑:只需要把刚插入到末尾的新元素,向前逐个比较交换到合适的位置即可,不需要全量排序。
- 新增元素的下标固定是
elements.size - 1,我们需要拿它和前一位元素比较,前一位元素的下标就是elements.size - 2,这就是index的初始值 - 后续比较直接复用
index和index+1作为相邻元素的下标,不需要额外调整偏移量,逻辑更简洁。
问题2:原代码与修改后的代码看起来都存在数组越界访问的情况,为何只有修改后的代码触发了越界错误?
核心原因是逻辑与(&&)的短路特性,以及你修改后的代码判断条件和数组访问逻辑不匹配:
原代码不会越界的原因
原代码的while判断是:
while (index >= 0 && elements[index + 1].compareTo(elements[index]) > 0)
&&会先判断左边的条件,只要左边不成立,右边的代码完全不会执行:
- 比如你第一次加1个元素,数组长度为1,
index = 1-2 = -1,左边index >=0直接不成立,整个循环直接跳过,根本不会执行后面的数组访问逻辑,自然不会越界 - 只要左边
index >=0成立,index的取值范围是0 ~ size-2,对应index+1的取值范围是1 ~ size-1,两个下标都在数组合法范围内,不会越界。
修改后的代码触发越界的原因
你修改后的代码判断逻辑和数组访问完全不匹配:
var index = count // 这里count等于数组长度size while (index >= 0 && elements[index - 1].compareTo(elements[index - 2]) > 0)
还是拿首次加1个元素的场景举例:
- 数组长度为1,
index初始值为1,左边index >=0成立,会继续执行右边的数组访问 - 此时
index-2 = 1-2 = -1,直接访问了下标为-1的数组元素,触发越界错误 - 就算后续index递减到0,左边
0 >=0仍然成立,index-1 = -1还是会触发越界,你的判断条件完全没有覆盖后面数组访问的合法性校验。
内容的提问来源于stack exchange,提问作者ntos
相关产品推荐
相关产品推荐

