zoukankan      html  css  js  c++  java
  • Algs4-2.2.16自然的归并排序

    2.2.16自然的归并排序。编写一个自底向上的归并排序,当需要将两个子数组排序时能够利用数组中已经有序的部分。首先找到一个有序的子数组(移动指针直到当前元素比上一个元素小为止),然后再找出另一个并将它们归并。根据数组大小和数组中递增子数组的最大长度分析算法的运行时间。
    图片
    import java.util.Arrays;
    public  class E2d2d16
    {
        public static void sort(Comparable[] a)
        {
          int N=a.length;
          if(N<=1) return;
          Comparable[] aux=new Comparable[N];
          int lo=0;
          int sp=-1;
          int hi=0;
          while(!(lo==0 && sp==N-1))
          {
            lo=0;
            while(lo<N-1)
            {
              sp=FindAscIndex(a,lo);
              hi=FindAscIndex(a,sp+1);
              if(sp==hi)
                 break;
              else
               {
                merge(a,aux,lo,sp,hi);
                lo=hi+1;
              }//end if
            }//end while
          }//end while
        }

        
        private static int FindAscIndex(Comparable[] a,int lo)
        {
          int N=a.length;
          if (lo==N-1) return lo;
          else if(lo>N-1) return lo-1;
          int i;
          for(i=lo+1;i<N && !less(a[i],a[i-1]);i++);
          return i-1;  
        }
         
        private static void merge(Comparable[] a,Comparable[] aux,int lo,int sp,int hi)
        {
           for(int i=lo;i<=hi;i++)
             aux[i]=a[i];
           //
           int i=lo;
           int j=sp+1;
           for(int k=lo;k<=hi;k++)
           {
             if(i>sp) a[k]=aux[j++];
             else if(j>hi) a[k]=aux[i++];
             else if(less(aux[j],aux[i])) a[k]=aux[j++];
             else a[k]=aux[i++];
           }
        }
       
        public static boolean isSorted(Comparable[] a)
        {
          int N=a.length;
          for(int i=1;i<N;i++)
            if(less(a[i],a[i-1])) return false;
          return true;
        }
       
        private static boolean less(Comparable v,Comparable w)
        {
            return v.compareTo(w)<0;
        }
       
        public static void main(String[] args)
        {
          Integer N=Integer.parseInt(args[0]);
          Comparable[] a =new Comparable[N];
          for(int i=0;i<N;i++)
            a[i]=StdRandom.uniform();
          sort(a);
          StdOut.printf("a size is:%d,a is sorted=%s",a.length,isSorted(a));
       }
      
    }
    分析:
    最坏情况:数组为逆序时,可以确保参与第一轮的归并的所有子数组的长度均为1,时此即为最坏情况。设数组长度为N=2^n,那么归并树深度为n,每一层查找子数组需要进行2N次数组访问,每一层归并需要2N次数组访问完成复制到辅助数组的操作,需要2N次数组访问完成比较,需要2N次访问完成辅助数组到a数组的复制,那么从底向上的自然归并最坏情况下需要访问8NlgN次数组。
    最长子数组为k时:数组的最长子数组为k时,的最好情况是第一轮的所有子数组的长度均为k,设数组长度为N=K*2^m,那么归并树深库为m,每一层查找子数组需要进行2N次数组访问,每一层归并需要2N次数组访问完成复制到辅助数组的操作,需要2N次数组访问完成比较,需要2N次访问完成辅助数组到a数组的复制,那么从底向上的自然归并最坏情况下需要访问8Nlg(N/k)次数组操作。

  • 相关阅读:
    51nod1229 序列求和 V2
    51nod 1228、1258 序列求和
    题解P3711:【仓鼠的数学题】
    伯努利数学习笔记的说...
    题解 P4692 【[Ynoi2016]谁的梦】
    积性函数与卷积
    题解 P5065 【[Ynoi2014]不归之人与望眼欲穿的人们】
    [Ynoi2018]末日时在做什么?有没有空?可以来拯救吗?
    [51nod1965]奇怪的式子
    PGCD2
  • 原文地址:https://www.cnblogs.com/longjin2018/p/9860101.html
Copyright © 2011-2022 走看看