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)次数组操作。

  • 相关阅读:
    General Problem Solving Techniques [Beginner-1]~H
    做HDU1010 带出来一个小问题
    HDU1009
    hdu1007
    hdu 1008
    HDU1006
    hdu 1005
    hdu 1004
    UVA 10970 第一次比赛 D题 (后面才补的)
    LightOJ 1317 第八次比赛 A 题
  • 原文地址:https://www.cnblogs.com/longjin2018/p/9860101.html
Copyright © 2011-2022 走看看