如有错误,感谢不吝赐教、交流
算法原理
使用分治模式:
1、分解:分解待排序的n个元素的序列成各具n/2个元素的两个子序列
2、解决:使用归并排序递归解决排序两个子序列
3、合并:合并两个已排列的子序列以产生已排序的答案
示例执行过程,红色部分是分割过程,蓝色是合并排序,线条上面的标号代表着递归执行的顺序。
归并排序伪代码
Java实现
public class MergeSort {
// 递归主体
public static void mergeSort(int [] arr, int p, int r) {
if (p < r) {
int q = p + (r - p) / 2; // 防止溢出
mergeSort(arr, p, q); // 对左边序列进行归并排序
mergeSort(arr, q+1, r); // 对右边序列进行归并排序
merge(arr, p, q, r); // 合并两个有序序列
}
}
// 具体归并排序
private static void merge(int[] arr, int p, int q, int r) {
int n1 = q - p + 1;
int n2 = r - q;
int [] left = new int[n1 + 1]; //多申请一个元素空间是为了赋值为整型最大作为边界(哨兵的用处)
int [] right = new int[n2 + 1];
for (int i = 0; i < n1; i++) {
left[i] = arr[p + i];
}
for (int i = 0; i < n2; i++) {
right[i] = arr[q + i + 1];
}
left[n1] = Integer.MAX_VALUE;
right[n2] = Integer.MAX_VALUE;
int i =0, j = 0;
for (int k = p; k <= r; k++) {
if (left[i] <= right[j] && left[i] != Integer.MAX_VALUE) {
arr[k] = left[i];
i = i + 1;
} else if (right[j] != Integer.MAX_VALUE) {
arr[k] = right[j];
j++;
}
}
}
public static void main(String[] args) {
int [] arr = new int[]{2, 4, 3, 8, 5, 9, 10};
int p = 0;
int r = arr.length - 1;
mergeSort(arr, p, r);
for (int a :
arr) {
System.out.println(a);
}
}
}
总结
归并排序的时间复杂度是O(nlogn)
需要使用额外空间
ps:计划每日更新一篇博客,今天由于内容原因会分几篇文章更新,今日2023-04-23,日更第七天,昨日更新:leetcode两数、三数、四数之和