归并排序算法分析与实现

归并排序运用了分治法的思想。
两个有序子数组可以以O(n)的时间复杂度进行合并。
当有序子数组长度s=1时,数组中有n/1个有序子数组,合并后有序子数组长度加倍变为2。
当有序子数组长度s=2时,数组中有n/2个有序子数组,合并后有序子数组长度加倍变为4。

当有序子数组长度s=n/2时,数组中有2个有序子数组,合并后有序子数组长度加倍变为n。
此时数组已经完全有序。
时间复杂度分析:
s的序列是:1,2,4, 8,….log2(n)
因此划分子数组的操作的时间复杂度是log(n)
合并子数组的时间复杂度是O(n)
因此归并排序的时间复杂度是:O(n*log(n))

public class MergeSortDemo {
    public static void main(String[] args) {
        int arr[]={2,3,5,1,4,9,8,7,6,0};
        MergeSort(arr);
        for (int i : arr) {
            System.out.println(i);
        }
    }
    public static void MergeSort(int[] x){
        int s=1;//字数组初始长度为1,只有单个元素的数组是有序的。
        int n=x.length;
        System.out.println("数组长度为:"+n);
        int[] y=new int[n];//用于存储合并后的数组
        while(s<n){
            //将 n/s 个长度为 s 的子数组 合并到y数组中,有序的子数组的长度变为2s
            MergePass(x,y,s,n);
            s+=s;//长度加倍
            //将 n/s 个长度为 s 的子数组 合并到y数组中,有序的子数组的长度变为2s
            MergePass(y,x,s,n);
            s+=s;//长度加倍
        }
    }
    /*
     * 合并总数组中的相邻子数组
     * s:子数组长度
     * n:总数组长度
     */
    public static void MergePass(int []x,int[] y,int s,int n){
        int i=0;
        //剩余的未合并段的长度大于等于2*s时
        while(n-i >= 2*s){
            //合并大小为s的相邻两段子数组
            Merge(x,y,i,i+s-1,i+s*2-1);
            i+=2*s;
        }

        //剩下的未合并元素个数小于2s

        if(n-i > s){//剩余的元素个数大于s
            Merge(x,y,i,i+s-1,n-1);
        }else {//剩余的元素个数小于等于s
            for(int j=i;j<=n-1;j++){
                y[j]=x[j];
            }
        }
    }
    /*
     * 合并两个有序数组为一个有序数组
     * l:第一个数组的左边界
     * m:第一个数组的右边界(第二个数组的左边界就是m+1)
     * r:第二个数组的左边界
     * 第一个数组:x[l...m]
     * 第二个数组:x[m+1...r]
     */
    public static void Merge(int[] x,int []y,int l,int m,int r){
        int i=l,j=m+1,k=l;
        while((i<=m)&&(j<=r)){
            if(x[i] <= x[j]){
                y[k++]=x[i++];
            }else {
                y[k++]=x[j++];
            }
        }
        if(i>m){
            for(int q=j;q<=r;++q){
                y[k++]=x[q];
            }
        }else {
            for(int q=i;q<=m;++q){
                y[k++]=x[q];
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值