Java 自下而上合并排序的实现中是否存在可能的勘误表

Java 自下而上合并排序的实现中是否存在可能的勘误表,java,algorithm,sorting,mergesort,Java,Algorithm,Sorting,Mergesort,下面的代码片段来自Robert SedgeWick和Kevin Wayne的《算法》一书 public class MergeBU { // This class should not be instantiated. private MergeBU() { } // stably merge a[lo..mid] with a[mid+1..hi] using aux[lo..hi] private static void merge(Comparable[

下面的代码片段来自Robert SedgeWick和Kevin Wayne的《算法》一书

public class MergeBU {

    // This class should not be instantiated.
    private MergeBU() { }

    // stably merge a[lo..mid] with a[mid+1..hi] using aux[lo..hi]
    private static void merge(Comparable[] a, Comparable[] aux, int lo, int mid, int hi) {

        // copy to aux[]
        for (int k = lo; k <= hi; k++) {
            aux[k] = a[k]; 
        }

        // merge back to a[]
        int i = lo, j = mid+1;
        for (int k = lo; k <= hi; k++) {
            if      (i > mid)              a[k] = aux[j++];  // this copying is unneccessary
            else if (j > hi)               a[k] = aux[i++];
            else if (less(aux[j], aux[i])) a[k] = aux[j++];
            else                           a[k] = aux[i++];
        }

    }

    /**
     * Rearranges the array in ascending order, using the natural order.
     * @param a the array to be sorted
     */
    public static void sort(Comparable[] a) {
        int n = a.length;
        Comparable[] aux = new Comparable[n];
        for (int len = 1; len < n; len *= 2) {
            for (int lo = 0; lo < n-len; lo += len+len) {
                int mid  = lo+len-1;
                int hi = Math.min(lo+len+len-1, n-1);
                merge(a, aux, lo, mid, hi);
            }
        }
        assert isSorted(a);
    }
//other methods
}

有人能帮我弄清楚吗。

你的分析不正确。合并过程如下

len=4
的过程中,它将合并两个子阵列
[0-3]
[4-7]
。最后两项未合并是正确的

len=8
时,它合并两个子阵列
[0-7]
[8-9]

当循环控制变量递增时,我怀疑您误解了。您应该在调试器中单步执行
sort
方法,注意两个循环中
lo
len
的值


顺便说一下,合并排序的定义中没有要求长度为2的幂。不过,处理非二次幂的数组会增加一点复杂性。这就是
merge
循环中的
if(i>mid)
if(j>hi
)条件的原因。

您的分析不正确。合并过程如下

len=4
的过程中,它将合并两个子阵列
[0-3]
[4-7]
。最后两项未合并是正确的

len=8
时,它合并两个子阵列
[0-7]
[8-9]

当循环控制变量递增时,我怀疑您误解了。您应该在调试器中单步执行
sort
方法,注意两个循环中
lo
len
的值


顺便说一下,合并排序的定义中没有要求长度为2的幂。不过,处理非二次幂的数组会增加一点复杂性。这就是
merge
循环中的
if(i>mid)
if(j>hi
)条件的原因。

是的,我没有正确计算len变量的值。对于长度为8的合并,len仅为4,因此可以进行另一次传递。内部循环有Math.min方法,因此检查也可以通过。感谢您帮助我看到分析中的缺陷。是的,我没有正确计算len变量的值。对于长度为8的合并,len仅为4,因此可以进行另一次传递。内部循环有Math.min方法,因此检查也可以通过。感谢您帮助我发现我分析中的缺陷。
public static void main(String[] args) {
        Integer[] array = {1,2,3,4,5,6,7,8,-50, -80};
        MergeBU.sort(array);
        System.out.println(Arrays.toString(array));
    }