归并排序是一种基于递归思想的排序算法,递归思想指的是在解决问题的时候,通过将一个大问题分解成多个小问题,并对每个小问题进行独立处理,最终合并解决方案得到整个问题的答案。在许多经典排序算法中,递归是不可或缺的核心部分。
归并排序是通过不断地将数组分割成更小的子数组,递归地对这些子数组进行排序,最后将这些排序好的子数组合并成一个完整的有序数组。
归并排序原理:
分割阶段:将待排序的数组递归地分割成两个子数组,直到每个子数组只有一个元素。
合并阶段:将子数组按顺序合并,合并时保证合并后的数组依然是有序的。
归并排序的最好的时间复杂度,平均时间复杂度和最坏的时间复杂度均为O(n log n)
由于归并排序采用了递归方式,通常它是稳定的排序算法,故其时间复杂度相同;但其需要额外的存储空间来存储子数组,对于每次递归的分割,需要创建新的临时数组,故空间复杂度为O(n)。
代码实现:
import java.util.Arrays; // 添加Arrays类,用于输出数组内的全部内容
public class Main {
// 归并排序的实现
public static void Sort(int[] arr) {
if (arr.length < 2) {
return; // 如果数组只有一个元素,直接返回
}
int mid = arr.length / 2; // 找到中间位置
int[] left = Arrays.copyOfRange(arr, 0, mid); // 分割出左半部分
int[] right = Arrays.copyOfRange(arr, mid, arr.length); // 分割出右半部分
// 递归排序左右两部分
Sort(left);
Sort(right);
// 合并排序好的左半部分和右半部分
add(arr, left, right);
}
// 合并两个已排序的子数组
public static void add(int[] arr, int[] left, int[] right) {
int i = 0, j = 0, k = 0;
// 合并两个数组,直到其中一个数组被完全合并
while (i < left.length && j < right.length) {
if (left[i] <= right[j]) {
arr[k++] = left[i++];
} else {
arr[k++] = right[j++];
}
}
// 如果左半部分还有剩余,继续合并
while (i < left.length) {
arr[k++] = left[i++];
}
// 如果右半部分还有剩余,继续合并
while (j < right.length) {
arr[k++] = right[j++];
}
}
public static void main(String[] args) {
int[] arr = {64, 25, 12, 22, 11, 37, 96, 81, 34, 78, 68, 25, 27}; // 待排序的数组
System.out.println("排序前的数组:");
System.out.println(Arrays.toString(arr));
// 调用归并排序方法进行排序
Sort(arr);
System.out.println("排序后的数组:");
System.out.println(Arrays.toString(arr));
}
}
运行结果