归并排序
- 将给定的包含n个元素的局部数组“分割”为俩个局部数组,每个数组包含 n/2 个元素。
- 对两个局部数组分别进行归并排序。
- 通过归并把两个已经排序的局部数组“整合”成一个数组。
举例:以 a = [9,6,7,2,5,1,8,4,2]进行归并排序
注:红色数字代表执行顺序。
代码:
import java.util.Arrays;
public class MergeSort {
public static void mergeSort(int[] arr, int left, int right) {
//直到分割到单个元素,停止分割
if(left+1<right) {
int mid = (left+right) / 2;
//分割为2个数组
mergeSort(arr, left, mid);
mergeSort(arr, mid, right);
//合并2个数组
merge(arr, left, mid, right);
}
}
public static void merge(int[] arr, int left, int mid, int right) {
//申请额外空间存储排序结果
int[] result = new int[right - left];
int i = 0, p1 = left, p2 = mid;
// 比较分割的数组的元素,哪个小,把那个元素填入result中
while(p1 < mid && p2 < right) {
result[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
}
//循环结束,把剩余的元素依次加入到result中
// 以下两个while只有一个会执行
while(p1 < mid) {
result[i++] = arr[p1++];
}
while(p2 < right) {
result[i++] = arr[p2++];
}
// 把最终的排序的结果复制给原数组
for(i = 0; i < result.length; i++) {
arr[left + i] = result[i];
}
}
public static void main(String[] args) {
int[] a = {9,6,7,2,5,1,8,4,2};
mergeSort(a, 0, a.length);
System.out.println(Arrays.toString(a));
}
}
结果:[1, 2, 2, 4, 5, 6, 7, 8, 9]
总结:
- 一般来说,n 个数据大致会分为 log2 n 层。由于每层执行归并的总复杂度为 O(n), 所以归并排序的时间复杂度为 O(nlogn)。
- 归并排序包含不相邻元素之间的比较,但并不会直接交换。在合并两个已排序数组时,如果遇到了相同元素,只要保证前半部分数组优先于后半部分数组,相同元素的顺序就不会颠倒。因此归并排序属于稳定的排序算法。
- 归并排序在处理过程中,需要临时占用一部分内存空间。所以归并排序的空间复杂度为O(n)。
来源:CSDN
作者:爱吃鱼的ねこ
链接:https://blog.csdn.net/weixin_43982698/article/details/104222275