概念
归并排序: 归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
优点: 时间复杂度O(n*logn),空间复杂度S(n),是一种稳定的算法(保证大小相同的元素排序后的顺序不变)
算法思想: 将多个有序表合并成一个新的有序表。无序 → 部分有序 → 有序
简单图解
有一串无序数组
1. 拆分 首先将他们无限二分,直到每一块只有一个元素
我们就会得到n个元素
2. 归并 将拆分的多个序列两两排序组合形成新的序列,直到合成所有序列
归并时创建一个临时数组来保存需要排序的数据,然后定义两个指针分别指向两个待排序合并的序列,比较两个指针的值来放入数组完成排序合并
代码实现
public class MergeSort {
public void mergeSort(int[] arr, int left, int right) {
// 左大于右则不需要继续拆分
if (left >= right) {
return;
}
// 找到中间点
int mid = (left + right) / 2;
// 以中间点为间隔对左右分别继续排序直到剩余一个元素
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
// 比较两个有序序列的大小,如果左边比右边大则排序合并
if (arr[mid] > arr[mid + 1]) {
merge(arr, left, mid, right);
}
}
private void merge(int[] arr, int left, int mid, int right) {
int[] aux = new int[right - left + 1];
for (int i = 0; i < aux.length; i++) {
aux[i] = arr[i + left];
}
// 定义左边序列指针
int i = 0;
// 定义右边序列指针
int j = mid + 1 - left;
// 将拆分数组排序合并到原数组
for (int k = left; k <= right; k++) {
if (i > mid - left) {
// 左边小的已经排序完毕 指针超过拆分后数组的长度 此时直接将右边指针所指的数据放入
arr[k] = aux[j];
// 放入后右指针后移
j++;
} else if (j > right - left) {
// 则表明右边序列指针已经超过长度 将左边序列指针所指的值直接放入数组 指针后移
arr[k] = aux[i];
i++;
} else if (aux[i] <= aux[j]) {
// 左指针所指的值小于等于右指针的值,直接放入数组后左指针后移
arr[k] = aux[i];
i++;
} else {
// 和上面相反
arr[k] = aux[j];
j++;
}
}
}
}