
本教程深入探讨如何在不依赖`java.util.arrays`包的情况下,实现递归归并排序算法。文章将详细介绍自定义数组切片(`copyofrange`替代)的方法,并提供标准的二路合并函数实现。此外,还将扩展讨论如何高效地实现三路合并函数,通过示例代码和专业讲解,帮助读者全面掌握归并排序的核心原理与实践技巧。
归并排序是一种基于分治策略的高效排序算法。其基本思想是将待排序数组递归地分成两半,直到每个子数组只包含一个元素(自然有序),然后将这些有序的子数组两两合并,最终得到一个完全有序的数组。
归并排序的核心在于两个步骤:
在Java中,Arrays.copyOfRange是一个非常方便的工具,用于从现有数组中复制指定范围的元素到一个新数组。然而,在某些特定场景下,例如限制外部包依赖或出于学习目的,我们需要手动实现此功能。
Arrays.copyOfRange(original, from, to) 的行为是从 from(包含)索引到 to(不包含)索引复制元素。我们可以通过一个简单的循环来实现它:
立即学习“Java免费学习笔记(深入)”;
/**
* 自定义数组切片方法,功能等同于 Arrays.copyOfRange
*
* @param original 原始数组
* @param from 起始索引(包含)
* @param to 结束索引(不包含)
* @return 包含指定范围元素的新数组
*/
private static int[] copyArray(int[] original, int from, int to) {
// 检查索引有效性,防止越界或创建负长度数组
if (from < 0 || to > original.length || from > to) {
throw new IllegalArgumentException("Invalid 'from' or 'to' indices.");
}
int[] result = new int[to - from];
for (int i = from; i < to; i++) {
result[i - from] = original[i];
}
return result;
}将此自定义切片方法集成到归并排序中,mergeSort函数如下:
public static void mergeSort(int[] A) {
if (A.length > 1) {
int mid = A.length / 2;
// 使用自定义的 copyArray 方法代替 Arrays.copyOfRange
// 左子数组包含从0到mid-1的元素
int[] leftArray = copyArray(A, 0, mid);
// 右子数组包含从mid到A.length-1的元素
int[] rightArray = copyArray(A, mid, A.length);
mergeSort(leftArray);
mergeSort(rightArray);
// 将排序后的左右子数组合并回原始数组A
merge(A, leftArray, rightArray);
}
}注意事项:
merge函数是归并排序的核心,它负责将两个已排序的子数组合并成一个更大的有序数组。合并过程中,我们通常需要三个指针:一个指向结果数组,两个分别指向两个待合并的子数组。
/**
* 将两个已排序的子数组合并回主数组
*
* @param mainArray 目标主数组,用于存放合并结果
* @param leftArray 已排序的左子数组
* @param rightArray 已排序的右子数组
*/
public static void merge(int[] mainArray, int[] leftArray, int[] rightArray) {
int i = 0; // leftArray 的当前索引
int j = 0; // rightArray 的当前索引
int k = 0; // mainArray 的当前索引
// 比较左右子数组的元素,将较小的元素放入主数组
while (i < leftArray.length && j < rightArray.length) {
if (leftArray[i] <= rightArray[j]) {
mainArray[k++] = leftArray[i++];
} else {
mainArray[k++] = rightArray[j++];
}
}
// 将 leftArray 中剩余的元素复制到主数组
while (i < leftArray.length) {
mainArray[k++] = leftArray[i++];
}
// 将 rightArray 中剩余的元素复制到主数组
while (j < rightArray.length) {
mainArray[k++] = rightArray[j++];
}
}将合并操作从两路扩展到三路,即同时合并三个已排序的数组,其基本思想仍然是不断从所有当前有元素的数组中选取最小的元素放入结果数组,并推进相应数组的指针。
实现三路合并的一种直接方法是维护三个数组的当前指针,并在每次迭代中找出这三个指针所指向元素中的最小值。
/**
* 合并三个已排序的数组
*
* @param a 第一个已排序数组
* @param b 第二个已排序数组
* @param c 第三个已排序数组
* @return 合并后的新数组
*/
public static int[] mergeArrays3(int[] a, int[] b, int[] c) {
int[] result = new int[a.length + b.length + c.以上就是Java递归归并排序与自定义数组切片及多路合并教程的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号