【问题标题】:Java merge sort recursion strangenessJava合并排序递归奇怪
【发布时间】:2018-06-21 05:14:10
【问题描述】:

我正在对排序算法进行一些评论,因为它们实际上在我的现实生活中并不经常出现,而这一点让我发疯了。我也有一段时间没学过 Java,所以我想也许我忘记了一些语言 esotarica,但我不这么认为。

我发现成功或失败取决于我如何进行递归调用来拆分数组。因此,如果我使用拆分调用的返回值作为合并调用的参数,它就可以工作。但是,如果我先递归调用拆分,然后调用合并,它会失败。但是,在我看来,它们都应该起作用。这似乎与堆栈的展开方式有关,但我无法完全理解它。

static Comparable[] mergesort(Comparable[] src) {
    if (src.length < 2)
        return src;

    int middle = src.length / 2;
    if (src.length % 2 > 0)
        middle++;

    Comparable[] left = new Comparable[src.length / 2];
    Comparable[] right = new Comparable[middle];

    System.arraycopy(src, 0, left, 0, left.length);
    System.arraycopy(src, src.length / 2, right, 0, right.length);

    // THIS DOESN'T WORK, BUT I DON'T KNOW WHY
    // mergesort(left);
    // mergesort(right);
    // return mergearrays(left, right);
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    // 
    // THIS ONE DOES WORK
    // 
    return mergearrays(mergesort(left), mergesort(right));
}

static Comparable[] mergearrays(Comparable[] left, Comparable[] right) {

    Comparable[] retval = new Comparable[left.length + right.length];

    int i = 0, j = 0, k = 0;
    for (; i < left.length && j < right.length;) {
        if (left[i].compareTo(right[j]) >= 0) {
            retval[k++] = right[j++];
        } else
            retval[k++] = left[i++];

    }

    while (k < retval.length) {
        if (i < left.length) {
            retval[k++] = left[i++];
        }
        if (j < right.length) {
            retval[k++] = right[j++];
        }
    }

    return retval;
}

【问题讨论】:

标签: java recursion mergesort


【解决方案1】:

您的mergearrays 方法创建了一个新数组,其中存储了合并后的排序数组。因此,如果您不使用 mergesort(left) 和 mergesort(right) 返回的数组(它们本身是由先前对 mergearrays 的调用创建的数组),您将丢弃已排序的数组并传递未排序的数组(left 和 @987654326 @) 到mergearrays。

因此这段代码是错误的:

mergesort(left); // returns a new sorted array which you ignore, doesn't modify left
mergesort(right); // returns a new sorted array which you ignore, doesn't modify right
return mergearrays(left, right); // merges two unsorted arrays, and therefore is wrong

虽然这段代码是对的:

// merges the two sorted arrays returned by mergesort(left) and mergesort(right)
return mergearrays(mergesort(left), mergesort(right));

一些合并排序实现在原始数组上执行合并步骤(即它们对数组进行排序而不是返回一个新的排序数组),在这种情况下,mergearrays 方法和 mergesort 都不需要返回任何内容,并且以下可以工作:

mergesort(left);
mergesort(right);
mergearrays(left, right);

【讨论】:

  • 谢谢。我通过捕获返回值并使用它们来验证,这也有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-15
  • 2016-04-19
  • 2018-07-26
  • 2015-03-02
  • 1970-01-01
  • 1970-01-01
  • 2021-11-06
相关资源
最近更新 更多