【问题标题】:Merge sort algorithm error归并排序算法错误
【发布时间】:2015-11-08 22:25:11
【问题描述】:

大家好,我一直在 Eclipse 中使用 java 开发合并排序器应用程序。由于某种原因,我无法弄清楚,这让我很生气......

这是我正在使用的主文件

public class MergeSorter {

    public Integer[] sort(Integer[] array) {
        return mergesort(array);
    }


    private Integer[] mergesort(Integer[] array) {
      if(array.length > 1) {
          Integer[] left = new Integer[array.length /2];
          Integer[] right = new Integer[array.length - left.length];

          mergesort(left);
          mergesort(right);

          merge(left, right);
        }
        return array;
    }


    public Integer[] merge(Integer[] left, Integer[] right) {
        int leftI = 0;
        int rightI = 0;
        int newI = 0;
        Integer[] newArr = new Integer[left.length + right.length];

        while (leftI < left.length && rightI < right.length) {
            if (left[leftI] < right[rightI]) {
                newArr[newI] = left[leftI];
                leftI++;
            } else {
                newArr[newI] = right[rightI];
                rightI++;
            }
            newI++;
        }

        // Either the left or the right may still have elements
        for (int i = leftI; i < left.length; i++) { // left
            newArr[newI] = left[i];
            newI++;
        }
        for (int i = rightI; i < right.length; i++) { // right
            newArr[newI] = right[i];
            newI++;
        }
        return newArr;
    }


    public void printCollection(Integer[] items) {
        for (int i = 0; i < items.length; i++) {
            System.out.print(items[i] + " ");
        }
        System.out.println();
    }
}

还有一个驱动程序文件已经完成了运行此代码的所有工作。有人告诉我,我需要将合并排序器类泛型为使用 arrayLists 而不是数组,但我不知道该怎么做。我在想这是我需要使用 List 的地方吗?但不确定,感谢任何帮助

【问题讨论】:

  • 您使用盒装Integer 类型而不是原始int 是否有原因?
  • 它会给你什么错误?
  • 识别问题(例如:您可以在集成之前测试 private 方法 - 因为在您调用 mergesort 时,leftright 中没有任何内容)并提供输入,您的实际输出和预期输出。
  • 在比较中尝试使用valueOf(),即尝试将left[leftI] &lt; right[rightI]更改为left[leftI].valueOf() &lt; right[rightI].valueOf()
  • 是时候学习如何调试了。

标签: java eclipse mergesort


【解决方案1】:

你的逻辑中有两个主要的整体。首先,您的归并排序无论如何都会返回它的输入。其次,您的合并数组永远不会被存储。

private Integer[] mergesort(Integer[] array) {
  if(array.length > 1) {
      Integer[] left = new Integer[array.length /2];
      Integer[] right = new Integer[array.length - left.length];

      mergesort(left); //problem 1.5: more on this later...
      mergesort(right);

      merge(left, right); //problem 2: stored array is returned but not stored
    }
    return array; //problem 1: returns array unchanged
}

解决问题 2 很简单。我们只需要将输出分配给一个字段,如下所示:

Integer[] result = merge(left,right);

array = merge(left,right);

使用其中一个或这些,resultarray 将不会保留在 merge() 中完成的工作。您选择的策略取决于您是否要修改输入。

这种关系实际上可能与直觉相反,但如果您希望输入保持不变,您可以使用第二行,现在问题 1 也已解决,因为我们已更改 array。 (输入没有改变,因为 Java 是 pass-by-value 这意味着 array 是一个新字段,与您的输入具有相同的数组,而不是包含该数组的同一字段,因此赋值使单独的字段array 中的数组而不触及原始文件)。不幸的是,这个解决方案给我们留下了问题 1.5,因为我们没有通过调用 mergesort() 来更改 leftright,在这种情况下,我们需要像处理 merge() 的结果一样存储。

如果您想mergesort() 更改输入数组(这不是一个不合理的想法),那么我们需要创建上面给出的单独的Integer[] results 并将其值复制到保存为 int array 的数组中。这也说明了问题 1.5,但可能会改变您方法的意图。

编辑: 我忽略了第三个问题。在mergesort() 中,您创建了leftright,但它们从未被填充。您应该将array 中的值复制到您的leftright 两半中。比如:

for(int i=0; i<left.length; i++) left[i] = array[i];
for(int i=0; i<right.length; i++) right[i] = array[left.length+i];


现在回答您的第二个问题,使用ArrayList&lt;Integer&gt; 完成您所做的每一件事应该不难。 The documentation 列出所有方法,您可以经常将ArrayList 视为数组(执行而不是array[i]array[i]=value,您必须使用方法array.get(i)array.set(i,value))。但是,您可以使用诸如 array.add(value) 之类的方法来简化事情,该方法将 value 放在列表的末尾,这样您就不必跟上末尾的实际位置。

希望这可以帮助您准确了解问题所在并解决它们,以便您的大脑可以为编程提供的所有其他精彩细节而烦恼

【讨论】:

  • 非常感谢您的帮助!帮了我很多。我坚持的最后一件事就是通过 ArrayLists 使其通用。我是否必须将整个方法名称更改为 Integer[] merge sort(.....);完全不同的东西?
  • 是的。您需要使用ArrayList&lt;Integer&gt; 而不是Integer[]。它们实现了类似的行为,但不可互换。
  • 好的,我现在正在处理这个问题。但是,当我继续更改它时,我会在我的合并排序方法中遇到任何左右的 array.length 以及诸如此类的错误。这是我完全迷路的地方..
  • ArrayList 需要使用它自己的方法。阅读文档以了解每个文档的功能并找出您需要的文档。如果您无法从中有所收获,您可以尝试搜索第三方“ArrayList 教程”。 Java 自己的tutorialscollectionlist 之类的抽象形式对其进行了介绍,但也可能值得一看。祝你好运。
  • @np0212,我又错过了一件事。如果给您带来任何问题,我深表歉意。
猜你喜欢
  • 1970-01-01
  • 2015-05-28
  • 1970-01-01
  • 2015-01-21
  • 1970-01-01
  • 2017-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多