基础算法-归并排序

来源:互联网 发布:高达ma 知乎 编辑:程序博客网 时间:2024/05/17 03:16

归并排序

思想:如果需要排序的数组分为两个部分,左边是有序的,右边也是有序的(都是升序或者都是降序),那么将两个区间合并为有序的只需要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);    }}
0 0