描述
归并排序采用了“分治”的思想
“分”:将大序列逐步分为一个个小序列,可以理解为递归拆分子序列的过程,递归深度为log2n
“治”:再将两个有序的小序列排序编回有序的大序列,两个小序列各需要一个指针逐步向后移动,所指元素比对由小至大放入temp,完成后,再将temp中已经完成排序的大序列copy进原序列,完成本次“治”;继续递归,直至整个序列排序完成
代码实现
/**
* 归并排序
*/
public class MergeSort {
public static void main(String[] args) {
int[] arr = {9, 8, 7, 6, 5, 4, 3, 2, 1};
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] arr) {
//在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间
int[] temp = new int[arr.length];
sort(arr, 0, arr.length - 1, temp);
}
private static void sort(int[] arr, int left, int right, int[] temp) {
if (left < right) {
int mid = (left + right) / 2;
//左边归并排序,使得左子序列有序
sort(arr, left, mid, temp);
//右边归并排序,使得右子序列有序
sort(arr, mid + 1, right, temp);
//将两个有序子数组合并操作
merge(arr, left, mid, right, temp);
}
}
private static void merge(int[] arr, int left, int mid, int right, int[] temp) {
//左序列指针
int i = left;
//右序列指针
int j = mid + 1;
//临时数组指针
int t = 0;
while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) {
temp[t++] = arr[i++];
} else {
temp[t++] = arr[j++];
}
}
//将左边剩余元素填充进temp中
while (i <= mid) {
temp[t++] = arr[i++];
}
//将右序列剩余元素填充进temp中
while (j <= right) {
temp[t++] = arr[j++];
}
t = 0;
//将temp中的元素全部拷贝到原数组中
while (left <= right) {
arr[left++] = temp[t++];
}
}
}
性能
归并排序的最坏、最好、平均时间复杂度都是O(nlogn),能用到完全二叉树排序的算法都不会太慢
以为需要一个相同大小的序列作为temp,所以它的空间复杂度是O(n)
相同值的元素的相对位置不会发生改变,所以它是稳定的
本文深入探讨了归并排序的原理,包括其“分治”思想,详细阐述了代码实现过程,并分析了算法性能。归并排序在最坏、最好、平均情况下的时间复杂度均为O(nlogn),但需要额外的O(n)空间,因此是稳定的排序算法。
1万+

被折叠的 条评论
为什么被折叠?



