算法之归并排序

归并:将俩个有序的数组归并成一个更大的有序数组。很快人们就根据归并的这个操作发明了一种简单的递归排序算法:归并排序。 要将一个数组排序,可以先(递归地)将它分成俩半分别排序,然后将结果归并起来。

优点:将任意长度为 N 的数组排序所需时间和 NlogN 成正比;

缺点:所需的额外空间和 N 成正比。

 

原地归并抽象方法:

public static void merge(Comparable[] a, int lo, int mid, int hi){
    //将a[lo..mid] 和 a[mid+1..hi] 归并,俩个有序数组
    int i = lo, j = mid + 1;

    //辅助数组
    for(int k = lo; k <= hi; k++) //将a[lo..hi] 复制到aux[lo..hi]
        aux[k] = a[k];
    
    for(int k = lo; k <= hi; k++){
        if(i > mid)                 a[k] = aux[j++]; //左半边取尽(取右半边元素)
        else if(j > hi)             a[k] = aux[i++]; //右半边取尽(取左半边元素)
        else if( less(a[i], a[j]) ) a[k] = aux[i++]; //左半边的当前元素小于右半边的当前元素(取左半边元素)
        else                        a[k] = aux[j++]; //左半边的当前元素大于等于右半边的当前元素(取右半边元素)
    }

}

 

自顶向下的归并排序

基于原地归并的抽象实现了一种递归归并,这也是应用高效算法设计中分治思想的最典型的例子。

public class Merge{
    private static Comparable[] aux; //归并所需的辅助数组
    public static void sort(Comparable[] a){
        aux = new Comparable[a.length];    //一次性分配空间
        sort(a, 0, a.length - 1);
    }
    
    public static void sort(Comparable[] a, int lo, int hi){
        //将a[lo..hi] 排序        
        if(lo >= hi) return;    //结束递归
        int mid = (lo + hi)/2;
        sort(a, 0, mid);         //将左半边排序
        sort(a, mid + 1, hi);    //将右半边排序
        merge(a, lo, mid, hi);   //归并结果(代码见 “原地归并抽象方法”) 
    }
}

 

自底向上的归并排序

public class MergeBU{
    private static Comparable[] aux;

    public static void sort(Comparable[] a){
        //进行lgN 次俩俩归并
        int N = a.length;
        aux = new Comparable[N];
        for(int sz = 1; sz < N; sz = sz*2)  //sz 子数组的大小,2的幂次方
            for(int lo = 0; lo < N-sz; lo += sz*2) //lo:子数组索引
                merge(a, lo, lo+sz-1, Math.min(lo+sz+sz-1, N-1);
    }

}

 

 

归并排序是一种渐进最优的基于比较排序的算法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值