归并排序,思想是将两个有序的数组归并成一个有序的数组。
它的时间复杂度是NlogN。
归并排序同时是分治算法的很好体现。
因为归并的前提是左右两边数组是有序的,因此我们得从最小的每两个长度开始进行归并,然后每4个长度开始归并,以此类推。
在较小长度的数组中,归并排序的效率无法证明与希尔排序的是快是慢,但是在较长长度的时候,是优于希尔排序的。
首先先理解归并的方法:
-
-
-
-
-
-
-
- public static void merge(int[] a,int[] copyA, int low, int mid ,int height){
-
-
- for(int i=low;i<=height;i++){
- copyA[i] = a[i];
- }
-
-
- int j = mid + 1;
- for(int i=low;i<=height;i++){
-
-
- if(i > mid){
- a[i] = copyA[j++];
- }else if(j > height){
- a[i] = copyA[i++];
- }else if(copyA[i] < copyA [j]){
- a[i] = copyA[i];
- }else{
- a[i] = copyA[j];
- }
- }
- }
自上而下的递归归并:
我们通过递归的方法自上而下递归调用自己:
-
-
-
-
- public static void sort1(int[] a){
- int[] copyA = new int[a.length];
- sort(a,copyA,0,a.length-1);
- SortTest.isSorted(a);
- }
-
-
-
-
-
-
-
-
- public static void sort(int[] a,int[] copyA, int low,int height){
- if(low >= height){
- return ;
- }
- int mid = (low + height)/2;
-
- sort(a,copyA,low,mid);
-
- sort(a,copyA,mid+1,height);
- merge(a,copyA,low,mid,height);
- }
它的过程如下:
![](https://img-blog.csdn.net/20161206002711610?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
自下而上的归并:
-
-
-
-
- public static void sort2(int[] a){
- int[] copyA = new int[a.length];
-
- for(int i=0;i<=a.length-1;i++){
- copyA[i] = a[i];
- }
-
-
-
-
- for(int i =0;i<=a.length/2;i++){
-
- for(int j=0;j<a.length -i;j++){
- merge(a,copyA,j,(j+j+i+1)/2,j+i+1-1);
- }
- }
- SortTest.isSorted(a);
- }
它的过程如下:
![](https://img-blog.csdn.net/20161206002832781?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
原文地址:http://blog.csdn.net/qq_25412055/article/details/53472086?ref=myread