归并排序的核心是不断地合并小数据集,直到整个集合都被排序。
上两张图,很直观地说明了递归的过程:
附上代码:
public class MergeSort {
//辅助数组
public static int[] aux;
/**
* 递归结束条件:hi <= lo
* 对左半数组排序,对右半数组排序,合并两个有序子数组
* @param a
*/
public static void sort(int[] a){
aux = new int[a.length];
sort(a, 0, a.length -1);
}
public static void sort(int[] a, int lo, int hi){
if(lo >= hi)
return;
int mid = lo + (hi - lo)/2;
//通过递归切分数组
sort(a, lo, mid);
sort(a, mid+1, hi);
//合并子数组
merge(a, lo, mid, hi);
}
/**
* 归并排序的核心是通过归并将子数组变得有序
* @param a
* @param lo
* @param mid
* @param hi
*/
public static void merge(int[] a, int lo, int mid, int hi){
//将元素复制到辅助数组
for(int k = lo; k <= hi; k++)
aux[k] = a[k];
//将辅助数组的元素排序到原数组
int leftStart = lo;
int rightStart = mid +1;
for(int k = lo; k <= hi; k++){
//左半边数组排序完毕,剩下右半边数组
if(leftStart > mid) {
a[k] = aux[rightStart++];
}
//右半边数组排序完毕,剩下左半边数组
else if(rightStart > hi){
a[k] = aux[leftStart++];
}
//左半边元素小
else if(aux[leftStart] <= aux[rightStart]){
a[k] = aux[leftStart++];
}
//右半边元素小
else{
a[k] = aux[rightStart++];
}
}
}
public static void main(String[] args){
int[] a = {5,1,2,8,5,3,2,15,2,7,1,2};
sort(a);
for(int i = 0; i< a.length; i++)
System.out.print(a[i] + " ");
}
}