归并排序

归并排序的思想

将数组中的元素递归地拆分为左右两部分,在左右两部分都排好序后,再将两个子数组归并为一个有序的大数组。归并排序是分治法的典型应用。
以下是原地归并且自顶向下归并的例子,归并的时间复杂度是NlogN.

    public void sort(Comparable[] a) {
        Comparable[] b = new Comparable[a.length];
        sort(a, 0, a.length-1, b);
        show(a);
    }

    void sort(Comparable[]a, int lo, int hi, Comparable[] b){
        //递归拆分数组,直到只有两个元素
        if(lo>=hi)
            return;

        int mid = lo + (hi-lo)/2;
        //左边排序
        sort(a, lo, mid, b);
        //右边排序
        sort(a,mid+1, hi, b);

        //左右归并
        merge(a, lo, mid, hi, b);
    }

    /**
     * 归并
     * @param a
     * @param low
     * @param mid 左边数组的右端下标
     * @param hi
     */
    void merge(Comparable[] a, int low,int mid,int hi, Comparable[] b) {
        //将数组元素复制到一个新数组中
        for(int i=low;i<=hi;i++){
            b[i] = a[i];
        }
        
        int m=low;
        int n=mid+1;
        //归并回原数组,由于两边数组都是已排序的,所以只需取出两者头部最小的依次放入原数组
        for(int i=low;i<=hi;i++) {
            if (m > mid)
                a[i] = b[n++];
            else if(n > hi)
                a[i] = b[m++];
            else if(less(b[m],b[n]))
                a[i] = b[m++];
            else
                a[i] = b[n++];
        }

    }

注意:以上归并首先是将原数组复制到数组b中,数组b写成层层传参,是为了复用,避免了每次归并都需要创建一个新数组。实际上也可以用其它方法保证复用。

还有另一种自底向上的归并,区别是先归并所有小数组。如先将所有2个元素的数组归并完成,再将所有相邻的数组归并为4元素,再全部归并为8元素。。。与上边始终是先解决完左边部分再从头解决右边部分有所区别

自顶向下:化整为零递归解决问题
自底向上:就是循序渐进的整体向前推进

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值