【问题标题】:Java mergesort algorithmJava归并排序算法
【发布时间】:2018-04-30 11:01:53
【问题描述】:
public class mergesort {
public static int[] mergesort (int[] input) {
    int length = input.length;
    if (length <= 1) {
        return input;
    }
    int median = length/2;
    int[] left = new int[median];
    int[] right = new int[length-median];
    for (int x = 0; x< median; x++) {
        left[x] = input[x];
    }
    for (int y = median; y < length; y++) {
        right[y-median] = input[y];
    }
    mergesort(left);
    mergesort(right);
    merge(left, right, input);
    return input;
}
public static int[] merge (int[] left, int[] right, int[] input) {
    int a = 0;
    int b = 0;
    int c = 0;
    int leftlength = left.length;
    int rightlength = right.length;
    while (a<leftlength && b<rightlength) {
        if (left[a] < right[b]) {
            input[c] = left[a];
            a++;
        } else {
            input[c] = right[b];
            b++;
        }
        c++;
    }
    return input;
}

public static void main(String[] args) {
    int[] inputArr = {45,23,11,89,77,98,4,28,65,43};
    mergesort mms = new mergesort();
    inputArr = mms.mergesort(inputArr);
    for(int i = 0; i < inputArr.length; i ++){
        System.out.print(inputArr[i]);
        System.out.print(" ");
    }
}

以上是我对合并排序算法的尝试。最后一个带有main(String[] args) 的代码块是一个测试运行,以查看我的算法是否有效。

代码仍然打印出一个数组(之前,它只是抛出了一个错误)。 但是,虽然算法应该打印

4, 11, 23, 28, 43, 45, 65, 77, 89,and 98, 

代码打印:

4 4 11 23 23 28 65 43 65 43, 

这显然不是预期的结果。

如何修复我的代码?

这是我第一次在这里发帖,所以如果我不允许发布此类材料等,请告诉我。

编辑:这是(令人惊讶的)原始代码的编辑版本。之前,代码抛出了一个错误,但现在至少它打印了一些东西。操作代码的一小部分(例如,将中位数更改为中位数+1 等)并没有奏效,而且我认为发布大量可能被视为试验和失败的结果并不重要对某些人来说微不足道。

是的,老实说,我不知道从这里去哪里。我让我的朋友检查代码,他使用调试器检查代码,但没有任何有意义的发现,因此发了这篇文章。

【问题讨论】:

  • 只是一个提示,1. 您在合并while (a&lt;leftlength &amp;&amp; b&lt;rightlength) 中的条件可能会提前终止,即使左侧或右侧数组中仍有可用的元素。 2.变量c不会被初始化为0。
  • @luksch 说得更合理一些,OP 是一个明显的初学者,能够生成自己的代码就足够了。你对他有什么期望?他尝试了一些合并排序的实现,但它不起作用。我相信他真的不知道从哪里开始修复。您可能会更有帮助,并给了他一些真正的提示。
  • @HonzaZidek 我完全赞同你的评论;注意 1. 实现包括递归,可以看作是一个重要的概念; 2. 不使用调试器很难找到错误。

标签: java algorithm sorting mergesort


【解决方案1】:

合并步骤的编写方式使其无法使用其整个输入。一旦要合并在一起的数组之一被完全消耗掉,循环就会终止,这是不希望的。这可以通过在后续步骤中使用任一数组来解决,如下所示。

public static int[] merge(int[] left, int[] right, int[] input)
{
    int a = 0;
    int b = 0;
    int c = 0;
    int leftlength = left.length;
    int rightlength = right.length;
    while (a < leftlength && b < rightlength)
    {
        if (left[a] < right[b])
        {
            input[c] = left[a];
            a++;
        }
        else
        {
            input[c] = right[b];
            b++;
        }
        c++;
    }
    while (a < leftlength)  // subsequent consumption of left
    {
        input[c] = left[a];
        a++;
        c++;
    }
    while (b < rightlength) // subsequent consumption of right
    {
        input[c] = right[b];
        b++;
        c++;
    }
    return input;
}

请注意,循环也可以放在一个循环中;有必要分别检查 ableftlengthrightlength 以决定是应该进行比较还是必须附加单个元素。在更紧凑的 C-ish 形式中,这可能如下所示。

public static int[] merge(int[] left, int[] right, int[] input)
{
    int a = 0;
    int b = 0;
    int c = 0;
    int cval = 0;
    int leftlength = left.length;
    int rightlength = right.length;
    while (a < leftlength || b < rightlength)   // <-- note the changed condition
    {
        if (a == leftlength)
        {
            cval = right[b++];
        }
        else if (b == rightlength)
        {
            cval = left[a++];
        }
        else
        {
            cval = left[a] < right[b] ? left[a++] : right[b++];
        }
        input[c++] = cval;
    }
    return input;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-21
    • 1970-01-01
    • 2017-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多