概述
归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
速度仅次于快速排序,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列。
算法稳定性
并排序是把序列递归地分成短序列,递归出口是短序列只有1个元素(认为直接有序)或者2个序列(1次比较和交换),然后把各个有序的段序列合并成一个有 序的长序列,不断合并直到原序列全部排好序。可以发现,在1个或2个元素时,1个元素不会交换,2个元素如果大小相等也没有人故意交换,这不会破坏稳定 性。那么,在短的有序序列合并的过程中,稳定是否受到破坏?没有,合并过程中我们可以保证如果两个当前元素相等时,我们把处在前面的序列的元素保存在结 果序列的前面,这样就保证了稳定性。所以,归并排序也是稳定的排序算法。
时间复杂度
平均时间复杂度均为O(nlogn)
归并过程
示例代码
/**
* 归并排序
* @author 吴庆龙
* Date: 2018/8/2
* Time: 11:02
*/
public class MergeSort {
public static void main(String[] args) {
int[] array = {7,3,2,4,1,8,0,9,5,6};
sort(array, 0, array.length - 1);
for (int i : array) {
System.out.print(i + " ");
}
System.out.println();
}
private static void sort(int[] array, int left, int right) {
// 递归终止条件
if (left >= right) {
return;
}
// 均分
int mid = (left + right) / 2;
// 排序左部分的
sort(array, left, mid);
// 排序右部分的
sort(array, mid + 1, right);
// 合并两个有序的数组
merge(array, left, mid, right);
}
private static void merge(int[] array, int left, int mid, int right) {
// 临时数组
int[] result = new int[array.length];
// 左边数组的起始索引
int l = left;
// 右边数组的起始索引
int m = mid + 1;
// 临时数组的索引
int index = 0;
// 同时循环两个数组, 比较两个数组的值, 保存在临时数组中
while (l <= mid && m <= right) {
if (array[l] < array[m]) {
result[index++] = array[l++];
} else {
result[index++] = array[m++];
}
}
// 剩余左边数组未比较的元素保存在临沭数组中
while (l <= mid) {
result[index++] = array[l++];
}
// 剩余右边数组未比较的元素保存在临沭数组中
while (m <= right) {
result[index++] = array[m++];
}
// 把临时数组中的值还原到原数组中的指定位置
for (int i = 0; i < index; i++) {
array[left + i] = result[i];
}
}
}
在每次merge的时候都会创建一个数组,这样比较浪费空间,可以在外部定义一个临时数组,然后用入参传进来。