归并排序非void实现失效求助:输出异常如何修复?
修复返回数组类型的归并排序实现
你的代码目前输出不符合预期,核心问题在于递归调用时没有接收排序后的子数组,且merge方法的逻辑是基于原数组的区间操作,而非对已排序的子数组进行合并。下面是修复后的完整代码,同时保持mergesort和merge方法返回数组的设计:
import java.util.Arrays; class Merges { public static void main(String args[]) { int[] A = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; // 打印原数组 for (int num : A) { System.out.print(num + " "); } System.out.println(); // 调用归并排序,接收返回的排序后数组 A = mergesort(A); // 打印排序后的数组 for (int num : A) { System.out.print(num + " "); } System.out.println(); } // 归并排序方法:接收数组,返回排序后的新数组 static int[] mergesort(int[] arr) { // 基线条件:数组长度<=1时直接返回 if (arr.length <= 1) { return arr; } // 将数组拆分为左右两部分 int mid = arr.length / 2; int[] left = Arrays.copyOfRange(arr, 0, mid); int[] right = Arrays.copyOfRange(arr, mid, arr.length); // 递归排序左右子数组 left = mergesort(left); right = mergesort(right); // 合并两个已排序的子数组并返回 return merge(left, right); } // 合并方法:接收两个已排序数组,返回合并后的新数组 static int[] merge(int[] left, int[] right) { int[] mergedArr = new int[left.length + right.length]; int i = 0, j = 0, k = 0; // 同时遍历左右数组,按顺序合并 while (i < left.length && j < right.length) { if (left[i] < right[j]) { mergedArr[k++] = left[i++]; } else { mergedArr[k++] = right[j++]; } } // 处理左数组剩余元素 while (i < left.length) { mergedArr[k++] = left[i++]; } // 处理右数组剩余元素 while (j < right.length) { mergedArr[k++] = right[j++]; } return mergedArr; } }
关键修复点说明:
- 简化
mergesort参数:不再需要l和r索引,直接对传入的数组进行拆分,更符合"返回排序后数组"的设计逻辑,避免原地修改原数组的混淆。 - 递归接收排序结果:每次递归调用
mergesort后,将返回的已排序子数组赋值给left和right,确保后续合并的是已经排序好的子数组。 - 重构
merge方法:让merge直接接收两个已排序的子数组,合并后返回新数组,而非基于原数组的区间操作,逻辑更清晰,也避免了原数组未被更新的问题。 - 使用
Arrays.copyOfRange拆分数组:替代手动循环赋值,快速获取左右子数组,代码更简洁。
运行这段代码后,会正确输出排序后的数组:1 2 3 4 5 6 7 8 9 10。
内容的提问来源于stack exchange,提问作者Manav
相关产品推荐
相关产品推荐

