Java中ArrayList<String>实现的插入排序仅能排序列表末尾,整体结果不正确
插入排序逻辑问题定位
核心bug根源
你在while循环中对compareTo()方法返回值的判断条件存在本质错误,这是导致排序完全失效的直接原因。
Java中字符串的compareTo()方法,返回值并不是固定的-1、0、1三个离散值:
- 当调用对象的字典序排在参数字符串前面时,返回负整数,具体值为两个字符串首个不匹配位置的字符Unicode编码差值
- 当两个字符串内容相等时返回0
- 当调用对象的字典序排在参数字符串后面时,返回正整数,同样是具体的字符差值,而非固定为1
你在代码中写的判断条件list.get(i).compareTo(current) == 1,会导致只有两个字符串的比较差值恰好为1的时候,循环才会触发。其余所有情况的比较结果都不会满足条件,自然不会执行位移排序操作。
你之前观察到的“仅末尾2-3组相邻名称被排序”的现象,完全匹配这个错误逻辑的运行结果:
- 从你的测试数据来看,只有「Margaret和Luke」、「Enzo和Daniel」这两对字符串的比较差值刚好为1,因此会被执行交换位移
- 其余所有字符串对的比较返回值都不等于1,完全不会进入循环做重排,最终就得到了你看到的仅局部交换的错误输出
修正方案
只需要把while循环里的判断条件从判断等于1,改成判断前序元素的字典序大于当前元素即可,不需要关心compareTo的具体返回数值:
public static void insertionSort(List<String> list) { for (int j = 1; j < list.size(); j++) { String current = list.get(j); int i = j - 1; // 修正点:只要前序元素字典序大于当前元素,就触发位移操作 while ((i > -1) && (list.get(i).compareTo(current) > 0)) { list.set(i + 1, list.get(i)); i--; } list.set(i + 1, current); } System.out.print(list); }
补充优化点
- 修复完成后,插入排序逻辑就可以正常工作:从第二个元素开始,逐个将当前元素插入到前面已排好序的子列表的对应位置,最终实现全列表的字典序升序排序。
- 你代码中的导入语句存在冗余:同时导入了
java.util.Scanner和java.util.*,可以删掉单独导入Scanner的行,在不影响功能的前提下让代码更整洁。
内容的提问来源于stack exchange,提问作者qui2gua
相关产品推荐
相关产品推荐

