手写板

/*
    测试用例:
    1. 数组长度为1的数组
    2. 数组长度为2的数组
    3. 数组长度为3的数组
    3. 数组长度为4的数组
    4. 前三个的常规输入是 s≤e ,如果输入的 s>r
*/

/*
    在数组 array 中 s~m 和 m~e 是两个已经拍好序的子序列,
    分别将它们拷贝到两个新数组中然后将两个新数组归并到 array 的 s~e 位置
    需要注意是否存在 (s==m||m==e) 的情况

    @param array 输入的数组
    @param s    : 数组的起始索引 (s)tart
    @param m    : 数组的中点索引 (m)iddle
    @param e    : 数组的终止索引 (e)nd
*/
public void merge(int[] array, int s, int m, int e){
    //将 s~m 拷贝到新数组 lArray
    int[] lArray = new int[m-s+1];
    for(int i = 0; i<lArray.length; i++){
        lArray[i] = array[s+i];
    }
    //将 m+1~e 拷贝到新数组 rArray
    int[] rArray = new int[e-m];
    for(int i = 0; i<rArray.length; i++){
        rArray[i] = array[m+1+i];
    }
    //归并 lArray 和 rArray
    for(int i=s,l=0,r=0; i<=e; i++){
        if(lArray[l]>rArray[r]){
            array[i] = rArray[r];
            r++;
        }else{
            array[i] = lArray[l];
        }
    }
}

/*
    @param array: 输入的数组
    @param s    : 数组的起始索引 (s)tart
    @param e    : 数组的终止索引 (e)nd
    首次启动本方法的时候 s = 0 ; e = n-1 。
*/
public mergeShort(int[] array,int s,int e){
    if(s>=e){
        if(s-e==1||s==e){
            println("要排序的子序列只有一个元素,不必排序和归并了。");
        }else{
            println("错误输入 s = " + s + ";e = " + e + ";");
        }
        return;
    }

    int m = (e+s)/2;            //计算出索引区间[(s)tart,(e)nd]中点处的索引 (m)iddle。
    mergeShort(array,s,m);
    mergeShort(array,m+1,e);    //当 s==e 的时候会造成 s>e 的输入。
    merge(array,s,m,e);
}

Last updated