插入排序代码为何部分输入运行正常,部分抛出ArrayIndexOutOfBoundsException: -1
问题成因分析
- 核心异常来源于
InsertionSort类中while循环的判断条件顺序错误,触发了Java短路求值机制导致的负下标访问。 - 原循环判断逻辑为
while(data[j-1]>key && j>=1),Java执行逻辑与判断时会从左到右短路求值:先计算左侧的data[j-1],再判断右侧的j>=1边界条件。 - 当插入的
key小于数组首个元素时,j会一路递减到0,此时下一轮循环会先计算data[j-1],也就是访问数组下标为-1的位置,直接抛出ArrayIndexOutOfBoundsException: -1。 - 对应测试用例的表现完全匹配这个逻辑:
- 测试输入1的首个元素6是数组中的最小值,所有待插入的
key都比6大,j永远不会递减到0的位置,自然不会触发负下标访问,所以代码可以正常运行。 - 测试输入2中存在比首元素10小的数值,
j会递减到0,触发负下标访问,抛出异常。
- 测试输入1的首个元素6是数组中的最小值,所有待插入的
解决方法
利用短路求值的特性,把边界判断移到逻辑与的最左侧,确保只有在j满足合法下标的前提下,才会去访问j-1位置的数组元素。
修正后的InsertionSort类完整代码如下:
public class InsertionSort { public void insertionSort(int data[]) { int i, j, key; for(i = 1; i < data.length; i++) { key = data[i]; j = i; // 调整判断顺序:先做边界校验,再做值比较 while(j >= 1 && data[j-1] > key) { data[j] = data[j-1]; j--; } data[j] = key; } } }
- 修正后,只要
j < 1,循环就会直接终止,不会执行右侧的data[j-1]访问,从根源上避免负下标越界。 - 调整逻辑后完全符合插入排序的算法逻辑,无论数组首元素是否为全局最小值,都可以正常完成排序。
内容的提问来源于stack exchange,提问作者cnayak
相关产品推荐
相关产品推荐

