Merge Sort 归并排序
0.前言
前面的文章已经分析了选择排序、插入排序、希尔排序等基础排序算法,本文将分析一个性能极高的排序算法——归并排序。在Java编程的时候,我们经常会使用到一个API:Arrays.sort(o),如果括号中的o是对象的话,那么该API就是调用归并排序算法(结合了插入排序)来完成排序的。顺带一提,如果括号里的o是java基本类型,那么该API就会调用快速排序算法。关于快速排序分析,将会在下一篇文章。
1.归并排序
原理
归并排序运用了递归的思想:
input:数组s
sort(数组s):
1.将输入的数组s对半分成两部分
2.对左右两部分(递归地)调用sort()
3.对左右两部分调用merge()进行合并
merge():
1.确定需要合并的两部分数组有序,否则不能合并
2.复制一个辅助数组aux,存放原数组
3.合并数组的操作就是将这两部分数组按序摆放后存入原数组,辅助数组提供原位置参考(这里可以使用插入排序算法来排序)
代码实现
public class Merge{
private static void merge(Comparable[] a, Comparable[] aux, int lo, int mid, int hi){
//保证需要合并的两部分是有序的
assert isSorted(a, lo, mid);
assert isSorted(a, mid+1, hi);
//赋值辅助数组
for (int k = lo; k <= hi; k++){
aux[k] = a[k];
}
int i = lo, j = mid+1;
for (int k = lo; k <= hi; k++){
if (i > mid) a[k] = aux[j++];//左侧已遍历完了
else if (j > hi) a[k] = aux[i++];//右侧已遍历完了
//选出最小的
else if (less(aux[j], aux[i])) a[k] = aux[j++];
else a[k] = aux[i++];
}
assert isSorted