zoukankan      html  css  js  c++  java
  • 归并排序

    归并:将两个有序数组归并成一个更大的有序数组。

    归并排序:要将一个数组排序,先将它分成两半分别排序,然后将结果归并起来。

    优点:能够保证将任意长度为N的数组排序所需的时间和NlgN成正比

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

    一、原地归并的抽象方法

      现将前半部分排序,再将后半部分排序,然后在数组中移动元素而不需要使用额外的空间。   

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

         方法描述:1、将所有元素复制到数组aux[]中

            2、进行归并,在第二个for循环中,若左半部分元素已经用完,取右半部分元素;右半部分元素用完,则取左半部分元素;右半边元素小于左半部分元素时,取右半部分元素;左半边元素小于右半边元素时,取左半边元素。

    二、自顶向下并归排序

            基于原地并归实现的一种递归并归。

    public class Merge{
      //并归所需要的辅助数组
      private static Comparable[] aux;
    
      public static void sort(Comparable[] a){
        aux = new Comparable[a.length];
        sort(a,0,a.length-1);
      }
    
      private static void sort(Comparable[] a,int lo,int hi){
        //将数组a[lo...hi]进行并归排序
        if(hi<=lo) return -1;
        int mid = (hi-lo)/2+lo;
        sort(a,lo,mid);//将数组左半边排序
        //将数组右半边排序
        sort(a,mid,hi);
        //此方法代码见一原地归并
        merge(a,lo,mid,hi);
      }
    }

    三、自底向上并归

           先并归微型数组,再成对并归得到的子数组,如此反复,知道将整个数组并归到一起。

           步骤:1、进行两两并归(把每个元素想象成一个大小为1的数组)

                      2、四四并归(将两个大小为2的数组并归成一个有4个元素的数组)

                      ......

    public class MergeBU{
         //并归所需要的辅助数组
         private static Comparable[] aux;
        //merge方法代码见第一部分
        public static void sort(Comparable[] a){
            //进行lgN次两两并归
            int N = a.length;
            aux = new Comparable[N];
            for(int sz = 1; sz<N;sz = sz+sz)
                for(int lo=0;lo<N-sz;lo+=sz)
                     merge(a,lo,lo+sz-1,Math.min(lo+sz+sz-1,N-1));
        }
    
    }

         自底向上的归并排序会多次遍历整个数组,根据子数组大小进行两两归并。子数组的大小sz的初始值为1,每次加倍。最后一个子数组的大小只有在数组大小是sz的偶数倍的时候才会等于sz(否则它会比sz小)。

  • 相关阅读:
    编程心得2----有疑惑,用代码说话
    Java的static关键字
    html中设置textbox的宽和高
    C#(winform)设置窗体的启动位置
    C#(winform)设置窗口置顶
    C#(winform)实现不同DPI控件自适应1
    设计模式--策略模式(strategy)
    requirejs原理深究以及r.js和gulp的打包【转】
    JavaScript中清空数组的三种方式
    localstorage本地存储
  • 原文地址:https://www.cnblogs.com/xiaoxli/p/9400691.html
Copyright © 2011-2022 走看看