
本文详解 java 中对二维 long 数组按第一列元素升序进行归并排序的完整实现,重点修复原代码中因索引偏移错误导致的数组覆盖问题,并提供可直接运行的健壮版本。
本文详解 java 中对二维 long 数组按第一列元素升序进行归并排序的完整实现,重点修复原代码中因索引偏移错误导致的数组覆盖问题,并提供可直接运行的健壮版本。
归并排序是一种经典的分治算法,适用于稳定、高效的自定义排序需求。当对二维数组(如 long[][] arr)按某列(例如第 0 列)排序时,关键在于:所有子数组操作必须严格基于当前递归区间 [s, e] 进行索引偏移计算。原代码中 merge 方法存在两处严重错误:
-
左半部分复制错误:
left[i] = arr[i];忽略了起始偏移s,导致始终从数组开头复制,而非[s, mid]区间; -
右半部分复制及后续填充错误:
right[i] = arr[i + n1];应为arr[mid + 1 + i];更严重的是,最后一段while (j 中误写为 <code>arr[k++] = left[j++](应为right[j++]),引发越界与数据错乱。
以下是修正后的完整、可运行代码:
public class MergeSort2D {
public static void mergeSort(long[][] arr, int s, int e) {
if (s < e) {
int mid = s + (e - s) / 2;
mergeSort(arr, s, mid);
mergeSort(arr, mid + 1, e);
merge(arr, s, mid, e);
}
}
public static void merge(long[][] arr, int s, int mid, int e) {
int n1 = mid - s + 1;
int n2 = e - mid;
// 创建左右临时数组(每行含 2 列)
long[][] left = new long[n1][2];
long[][] right = new long[n2][2];
// ✅ 正确复制:使用 s 和 mid+1 作为起点
for (int i = 0; i < n1; i++) {
left[i] = arr[s + i]; // 关键修复:加偏移 s
}
for (int i = 0; i < n2; i++) {
right[i] = arr[mid + 1 + i]; // 关键修复:加偏移 mid+1
}
int i = 0, j = 0, k = s;
// 归并:按第 0 列(arr[x][0])升序
while (i < n1 && j < n2) {
if (left[i][0] <= right[j][0]) {
arr[k++] = left[i++];
} else {
arr[k++] = right[j++];
}
}
// 复制剩余左半部分
while (i < n1) {
arr[k++] = left[i++];
}
// ✅ 修复:此处必须是 right[j++],不是 left[j++]
while (j < n2) {
arr[k++] = right[j++];
}
}
public static void main(String[] args) {
long[][] arr = {{1, 4}, {3, 6}, {8, 4}, {7, 7}};
mergeSort(arr, 0, arr.length - 1);
System.out.println("Sorted by 1st column:");
for (long[] row : arr) {
System.out.println(row[0] + " " + row[1]);
}
// 输出:
// 1 4
// 3 6
// 7 7
// 8 4
}
}注意事项与最佳实践:
- ✅ 始终使用
s + i和mid + 1 + i计算源数组索引,避免硬编码0; - ✅ 使用
而非 <code> 在比较中可保持排序稳定性(相同首值时相对顺序不变); - ⚠️ 若二维数组列数不固定(如非严格 2 列),建议将列索引作为参数传入
merge方法以增强通用性; - ? 对于生产环境,推荐使用
Arrays.sort(arr, Comparator.comparingLong(a -> a[0])),简洁且经过高度优化;但理解手动归并逻辑对算法能力提升至关重要。
该实现已通过多组边界测试(单元素、逆序、重复首值等),确保逻辑严谨、结果可靠。
立即学习“Java免费学习笔记(深入)”;


















