归并排序

归并排序

  1. 保证任意长度为N的数组排序所需时间和NlogN成正比
  2. 主要缺点是它所需的额外空间和N成正比

即将两个数组归并成一个更大的有序数组,可以先递归将它分成两半排序,再将结果归并起来

 原地归并 

实现归并的一种直截了当的方法是将俩个不同的有序数组归并到第3个数组中,将一个大数组排序时,我们需要进行很多次归并,因此每次归并都创建一个新数组来储存结果会带来问题,使用原地归并的方法,先将前半部分排序,再将后半部分排序,数组移动而不需要使用额外的空间

public static void main(Comparable[] a, int lo, int mid, int hi)
{   //将a[lo......mid] 与 a[mid+1.....hi] 归并
        int i=lo, int 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(a[j]<a[i])    a[k]=a[j++];
            else                  a[k]=aux[i++];
        } 
}   

 ①自顶向下的归并排序(使用递归)

public class Merge
{
        public static Comparable aux;    //归并所需的辅助数组
        public static void sort(Comparable[] a)
        {
            aux = new Comparable[a.length]    //分配空间
            sort(a, o, a.length);
        }

        public static void sort(Comparable[] a ,int lo ,int hi)
        {
            if(hi>=ho)    return;
            int mid =ho+(hi-ho)/2;
            sort(a ,ho ,mid);
            sort(a ,mid+1 ,hi);
            merge(a ,lo ,mid ,hi);    //原地归并,开头有
        }
}

  例如排序a[15],归并如下

                 lo       hi

  merge(a, 0, 0, 1);

  merge(a, 2, 2, 3);

  merge(a, 2, 2, 3);

  merge(a, 0, 1. 3);  归并0~3

  merge(a, 4, 4, 5);

  merge(a, 6, 6, 7);

  merge(a, 4, 5, 7);  归并4~7

  merge(a, 0, 3, 7);  归并0~7

  merge(a, 8, 8, 9);

  merge(a, 10, 10, 11);

  merge(a, 8, 9, 11);  归并8~11

  merge(a, 12, 12, 13);

  merge(a, 14, 14, 15);

  merge(a, 12, 13, 15); 归并12~15

  merge(a, 8, 11, 15);  归并8~15

  merge(a, 0, 7, 15);  归并0~15

 

②自底向上的归并排序

public class MergeBu
{
        private static Comparable[] aux;    //归并所需的辅助数组
        
        public static void sort(Comparable[] a)
        {            //进行lgN次俩俩归并
            aux = new Comparable[N];
            for(int sz=1; sz<a.length; sz=sz+sz)
                for(int lo=0; lo<a.length-sz; lo+=sz+sz)
                    merge(a, lo, lo+sz-1, Math.min(lo+sz+sz-1, a.length-1))
        }
}    

 

posted @ 2018-11-12 23:05  黄骏捷的博客  阅读(198)  评论(0编辑  收藏  举报