合并排序算法错误

时间:2015-11-08 22:25:11

标签: java eclipse mergesort

嘿,我一直在使用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();
    }
}

还有一个驱动程序文件,它可以完成所有操作以运行此代码。我被告知我需要将merger sorter类生成为使用arrayLists而不是数组,但我对如何这样做感到很遗憾。我在想这是我需要使用List的地方?但不确定,任何帮助表示赞赏

1 个答案:

答案 0 :(得分:2)

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

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是按值传递意味着array是一个与输入具有相同数组的新字段,而不是包含该数组的相同字段,因此赋值使得put字段array中的单独数组,不触及原始数据)。不幸的是,这个解决方案给我们留下了问题1.5,因为我们不会通过调用left来改变rightmergesort(),在这种情况下我们需要存储{的结果{ {1}}。

如果你想merge()更改输入数组(这不是一个不合理的想法),那么我们需要创建上面给出的单独mergesort()并将其复制到数组中持有int Integer[] results。这也会给问题1.5做广告,但可能会改变你方法的意图。

编辑: 我忽略了第三个问题。在array您已创建mergesort()left,但它们永远不会被填充。您应该将right的值复制到arrayleft个半部分。类似的东西:

right

现在回答你的第二个问题,用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]; 完成你所做的每一件事并不难。 The documentation列出了所有方法,您可以经常将ArrayList<Integer>视为数组(execpt而不是ArrayListarray[i]您必须使用方法array[i]=value和{{ 1}})。但是,您可以使用array.get(i)这样的方法来简化操作,array.set(i,value)array.add(value)放在列表的末尾,这样您就不必跟上结尾的位置。

希望这可以帮助您准确理解问题所处的位置并解决它们,以便您的大脑可以扼杀编程提供的所有其他精彩细节