基础算法-归并排序

归并排序

思想:如果需要排序的数组分为两个部分,左边是有序的,右边也是有序的(都是升序或者都是降序),那么将两个区间合并为有序的只需要o(n)的复杂度就可以完成。那么如果这两个区域不是有序的呢,可以递归的调用归并排序,直到区间的元素只有一个元素,那么这个区间就是有序的,回到上一层调用,左右两个区间已经有序的情况下,把它们合并在一起,那么这一层就有序了。直到回到了第一层,那么整个数组就有序了。


public class MergeSort {


    // [l,m] 区间升序, [m+1,r] 区间升序 ,通过 tmp[] 将它们合并仍然有序
    private static void merge(int a[],int l,int m,int r,int tmp[]){
        int i=l,j=m+1,k=0;
        while (i<=m&&j<=r){
            if(a[i]<a[j])
                tmp[k++]=a[i++];
            else
                tmp[k++]=a[j++];
        }
        while (i<=m)
            tmp[k++]=a[i++];
        while (j<=r)
            tmp[k++]=a[j++];
        for(i=0;i<k;i++)
            a[l+i]=tmp[i];
    }
    private static void mergeSortInner(int a[],int l,int r,int tmp[]){

        if(l<r){
            int m=(l+r)/2;
            mergeSortInner(a,l,m,tmp);//先递归排序,使得左边升序
            mergeSortInner(a,m+1,r,tmp);//递归排序,使得右边升序
            merge(a,l,m,r,tmp);//合并两个升序的区间为有序
        }
    }

    //一次性创建临时数组,避免每次合并时新建新的临时数组
    private static void mergeSort(int a[],int n){

        int tmp[]=new int[n];
        mergeSortInner(a,0,n-1,tmp);
    }

    public static void main(String[]args){

        int a[]=new int[100];
        SortUtil.randomArray(a);
        SortUtil.print(a);
        mergeSort(a,100);
        SortUtil.print(a);
    }

}

猜你喜欢

转载自blog.csdn.net/yzr1183739890/article/details/56678844