归并排序,从字面意思上理解,即合并的时候排序。
归并排序是分治法的一种,首先将待排数列分成1个一个元素,然后依次按大小合并。
排序过程
分
初始关键值 [49] [38] [65] [97] [76] [13] [27]
合
第一趟归并:(38,49) (65,97) (13,76) 27
第三趟归并:(38,49,65,97) (13,27,76)
第四趟合并:[13,27,38,49,65,76,97]
代码:
package merge;
import java.util.Arrays;
public class MergeSort {
public static void main(String[] args) {
int x[]={4,-5,0,3,-1,12,9,-7,8,-4,11};
int []a = new int[]{33,9,34,12,6,10,8,9,32,1};
int[] b = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
MergeSort sort = new MergeSort();
sort.NMergeSort(x);
System.out.println(Arrays.toString(x));
sort.mergeSort(a, 0, a.length - 1);
System.out.println(Arrays.toString(a));
System.out.println();
sort.mergeSort(b,0,a.length - 1);
System.out.println(Arrays.toString(b));
}
public void merge(int []a,int low,int middle,int high){//合并
int length = a.length;//将low到Middle ,Middle到high的元素按顺序合并
int []b = new int[length];//辅助数组
int k = 0;
int j = middle+1,i = low;
while(i <= middle && j <=high){
if(a[i]<a[j]) b[k++] = a[i++];//比较较小者填入数组
else b[k++] = a[j++];
}
while(i <= middle) b[k++] = a[i++];//若有元素没有填入完
while(j <= high) b[k++] = a[j++];
for(k = 0,i = low;i <= high;i++,k++){
a[i] = b[k];//将数组重新复制到a数组中
}
}
/**
* 非递归
*/
public void NMergeSort(int []a){
int size=1;//分治元素数量初始为1,按2的幂次递增
int length = a.length;
int low = 0;
int middle;
int high;
while(size < length){
//分治
low = 0;
while(low + size <= length-1){
middle = low + size - 1;//合并左边高位下标
high = middle + size;//带合并右边数组高位下标
if(high > length - 1){//如果右边数组中的数值不够size
high = length - 1;
}
merge(a,low,middle,high);//按size合并
low = high+1;//递增遍历整个数组
}
size*=2;
}
}
/**
* 递归
*/
public void mergeSort(int a[],int low,int high){
int middle;
if(low == high) return ;
else{
middle = (low+high)/2;
mergeSort(a, low, middle);//先分治
mergeSort(a,middle+1,high);
merge(a,low,middle,high);//再合并
}
}
}