归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

归并操作(merge),指的是将两个已经排序的序列合并成一个序列的操作。

对两个排序数组合并成一个有序数组,这个很简单

    public int[] merge(int[] A,int[] B){
        int aLen = A.length;
        int bLen = B.length;
        int cLen = aLen + bLen;
        int[] C = new int[cLen];
        int i=0;
        int j=0;
        int k=0;
        while(i<aLen && j<bLen){
            if(A[i] <= B[j]){
                C[k] = A[i];
                k++;
                i++;
            }else{
                C[k] = B[j];
                k++;
                j++;
            }
        }
        while(i<aLen){
            C[k] = A[i];
            k++;
            i++;
        }
        while(j<bLen){
            C[k] = B[j];
            k++;
            j++;
        }
        return C;
    }

这个时间复杂度O(N+M)

对于一个数组的时候,low - mid是有序的,mid+1--high是有序的,进行归并操作

    public void merge(int[] A,int low ,int mid ,int high){
        int len = high - low + 1;
        int[] C = new int[len]; // 只临时保存low - high大小的数组
        int i= low;
        int j = mid + 1;
        int k = 0;
        while(i <= mid && j<=high){
            if(A[i] <= A[j]){
                C[k] = A[i];
                k++;
                i++;
            }else{
                C[k] = A[j];
                k++;
                j++;
            }
        }
        while(i<= mid){
            C[k] = A[i];
            k++;
            i++;
        }
        while(j<= high){
            C[k] = A[j];
            k++;
            j++;
        }
        for(i = 0;i<len;i++){
            A[i + low] = C[i]; // 更新A
        }

    } 

 

归并排序工作原理:(假设序列共有n个元素): 

1.将序列每相邻两个数字进行归并操作(merge),形成floor(n/2)个序列,排序后每个序列包含两个元素 

2.将上述序列再次归并,形成floor(n/4)个序列,每个序列包含四个元素 

3.重复步骤2,直到所有元素排序完毕

    public void mergeSort(int[]A,int low,int high){
        if(low>=high)
            return;
        int mid = low + (high - low)/2;
        mergeSort(A,low,mid);// 左侧排序
        mergeSort(A,mid+1,high); // 右侧排序
        merge(A,low,mid,high); // 归并
    }

 

俨然的一种后序遍历的感觉

左侧排序了

右侧排序了

合并了排序数组

空间复杂度:O(N)

时间复杂度:O(NlogN)