嘿,我一直在使用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的地方?但不确定,任何帮助表示赞赏
答案 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);
使用其中之一或result
或array
将无法保留merge()
中完成的工作。您选择的策略取决于您是否要修改输入。
这种关系实际上可能是反直觉的,但是如果你希望你的输入保持不变,你可以使用第二行,现在问题1也解决了,因为我们已经改变了array
。 (输入未更改,因为Java是按值传递意味着array
是一个与输入具有相同数组的新字段,而不是包含该数组的相同字段,因此赋值使得put字段array
中的单独数组,不触及原始数据)。不幸的是,这个解决方案给我们留下了问题1.5,因为我们不会通过调用left
来改变right
和mergesort()
,在这种情况下我们需要存储{的结果{ {1}}。
如果你想merge()
更改输入数组(这不是一个不合理的想法),那么我们需要创建上面给出的单独mergesort()
并将其复制到数组中持有int Integer[] results
。这也会给问题1.5做广告,但可能会改变你方法的意图。
编辑: 我忽略了第三个问题。在array
您已创建mergesort()
和left
,但它们永远不会被填充。您应该将right
的值复制到array
或left
个半部分。类似的东西:
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而不是ArrayList
或array[i]
您必须使用方法array[i]=value
和{{ 1}})。但是,您可以使用array.get(i)
这样的方法来简化操作,array.set(i,value)
将array.add(value)
放在列表的末尾,这样您就不必跟上结尾的位置。
希望这可以帮助您准确理解问题所处的位置并解决它们,以便您的大脑可以扼杀编程提供的所有其他精彩细节