合并排序算法逻辑的合并功能是错误的

时间:2015-03-24 21:03:06

标签: java arrays algorithm mergesort

我正在尝试在Java中实现mergesort。我理解算法,但是在执行方面遇到了麻烦。这是我写的代码:

package sort;

import java.util.Arrays;

public class MergeSort {

public MergeSort() {

}

public static void main(String[] args) {

    int[] d = {26,14,72,34,622,483};
    MergeSort ms = new MergeSort();
    int[] results = ms.mergesort(d);
    for (int i = 0; i < results.length; i++) {
        System.out.println(results[i]);
    }

}

public int[] mergesort(int[] a) {

    System.out.println("Another call to merge sort");

    if (a.length <= 1) { return a;}

    int mid = a.length / 2;
    int[] left = Arrays.copyOfRange(a,0,mid);
    int[] right = Arrays.copyOfRange(a,mid + 1,a.length);

    left = mergesort(left);
    right = mergesort(right);

    int[] result = merge(left,right);
    return result;
}

private int[] merge(int[] b, int[] c) {
    System.out.println("Another call to merge");

    int[] result = new int[b.length+c.length];

    if (b.length == 0) {
        return c;
    } else if (c.length == 0) {
        return b;
    } else if (b[0] < c[0] && b.length == 1) {
        result[0] = b[0];
        for (int i = 1; i < result.length; i++) {
            result[i] = c[i -1];
        }
        return result;
    }else if (b[0] > c[0] && c.length == 1) {
        result[0] = c[0];
        for (int i = 0; i < result.length; i++) {
            result[i] = b[i-1];
        }
        return result;
    }
    else if (b[0] < c[0]) {
        result[0] = b[0];
        result = merge(result,merge(Arrays.copyOfRange(b,1,b.length),c));
        return result;
    } else if (b[0] > c[0]) {
        result[0] = c[0];
        result = merge(result,merge(b,Arrays.copyOfRange(c,1,c.length)));
        return result;
    } else {
        System.out.println("Fell to the bottom.");
        return result;
    }
}

}

问题是我的合并功能。我尝试在此处遵循此算法:http://discrete.gr/complexity/但我不断获得IndexOutOfBoundsExceptions因为如果数组的大小仅为1,则Arrays.copyOfRange没有索引1可以抓取。我试图在我的代码中解决这个问题,但它变得非常混乱。按照现在的方式,它会在函数中进行大量调用,然后抛出IndexOutOfBoundsException。我真的很感激这方面的一些帮助。我只是自己这样做,试图找出它,而不是作为家庭作业。

1 个答案:

答案 0 :(得分:1)

我建议迭代地实现合并而不是递归。合并也是一个糟糕的concat函数,在你的例子中使用,令人困惑(至少将它移动到一个单独的函数)。

在您的情况下,错误在这里:

    for (int i = 0; i < result.length; i++) {
        result[i] = b[i-1];
    }

我需要从1开始,否则i - 1 == -1,这绝不是有效的索引。

将来,请注意问题中发生异常的位置,并通过调试器运行程序,在这种情况下,它会立即显示问题。

编辑:好的,这仍然不会导致正确的程序。其他错误:

int[] right = Arrays.copyOfRange(a,mid + 1,a.length);
// needs to be "mid", not "mid + 1", read the doc on the function

EDIT2:最后一行需要:

else if (b[0] < c[0]) {
    result = merge(new int[]{b[0]},merge(Arrays.copyOfRange(b,1,b.length),c));
    return result;
} else if (b[0] > c[0]) {
    result = merge(new int[]{c[0]},merge(b,Arrays.copyOfRange(c,1,c.length)));
    return result;
} else {

否则,结果会很长。