排序算法——归并排序

归并排序遵循分治原则先将数组不断的递归二分打散,打散后再进行二二组合。原理如下数组:
分[1,2,3,4,5,6,7,8]

分[1,2,3,4],[5,6,7,8]

分[1,2],[3,4],[5,6],[7,8]

分[1],[2],[3],[4],[5],[6],[7],[8]

治:[2,1],[4,3],6,5],[8,7]

治:[4,3,2,1],[8,7,6,5]

治:[8,7,6,5,4,3,2,1]

如图所示,分治过程中先分后治,这里我们就用到了递归。所以他的空间需求较大。并且在该算法中还含有一个用来记录位置的缓存数组。

排序时间复杂度为:Nlog2N。

/**
 * 归并排序
 * @author DHH
 *
 */
public class Select extends Example {
    /**
     * 归并排序
     */
    //缓存数组用来排序的时候存储排序前的位置。
    private static Comparable[] b;
    /**
     * 排序方法,对外接口
     */
    public void sort(Comparable[] a){
        b=new Comparable[a.length];
        sort( a,0,a.length-1);
    }
    /**
     * 分治中的分方法,并且递归安排好治的顺序
     * @param a
     * @param lo
     * @param hi
     */
    public void sort(Comparable[] a,int lo,int hi){

        int mid=(hi+lo)/2;
        
        if(hi<=lo) return;
        //mid+1为起步,因为两位数的时候java向下取整,会有mid=lo的情况,无限递归。
        sort(a,lo,mid);
        sort(a,mid+1,hi);
        sort(a,lo,mid,hi);
    }
    /**
     * 分治中的治方法,
     * @param a
     * @param lo
     * @param hi
     */
    public void sort(Comparable[] a,int lo,int mid,int hi){
        //mid必须是+1为起步,因为数组只有两位数时mid可能会等于lo,有相同数字相比的情况,无法正常排序。
        int i=lo;
        int j=mid+1;
        //迁移数组
        for(int k=lo;k<=hi;k++){
            b[k]=a[k];
        }
        
        for(int k=lo;k<=hi;k++){
            //
            if(i>mid){
                a[k]=b[j++];
            }else if(j>hi){
                a[k]=b[i++];
            }else if(b[i].compareTo(b[j])>0){
                a[k]=b[i++];
            }else{
                a[k]=b[j++];
            }
        }
    }
    
    
    
    /**
     * 测试方法
     * @param args
     */
    public static void main(String[] args) {
        DATA[] dataArray=new DATA[15];
        dataArray[0]=new DATA(16);
        dataArray[1]=new DATA(6);
        dataArray[2]=new DATA(15);
        dataArray[3]=new DATA(8);
        dataArray[4]=new DATA(11);
        dataArray[5]=new DATA(23);
        dataArray[6]=new DATA(75);
        dataArray[7]=new DATA(4);
        dataArray[8]=new DATA(11);
        dataArray[9]=new DATA(60);
        dataArray[10]=new DATA(71);
        dataArray[11]=new DATA(24);
        dataArray[12]=new DATA(56);
        dataArray[13]=new DATA(31);
        dataArray[14]=new DATA(42);
        System.out.println(Arrays.toString(dataArray));
        Select select=new Select();
        select.sort(dataArray);
        System.out.println(Arrays.toString(dataArray));
    }
}

 

posted @ 2017-12-21 09:12  酒皇  阅读(197)  评论(0编辑  收藏  举报