Java新手。我正在关注一本书,并给出了一个关于quicksort的例子。我理解算法,但希望在每次递归之前打印数组,以真正了解较低和较高数组的情况。
我以为我只是声明一个单独的列表并使用较低的值,数据透视表和更高的值填充它,但它似乎抛弃了所有功能。递归似乎保持不变但实际上并没有排序。因此,它会溢出并退出。
我几乎可以肯定,我在这里缺少一个基本的Java概念。
评论中包含的所有内容都取自本书。注释行之间的界限是我自己的。
package quicksort;
import java.util.ArrayList;
import java.util.List;
public class App {
public static List<Integer> quicksort(List<Integer> numbers){
if (numbers.size() < 2){
return numbers;
}
final Integer pivot = numbers.get(0);
final List<Integer> lower = new ArrayList<>();
final List<Integer> higher = new ArrayList<>();
for (int i = 1; i < numbers.size(); i++){
if (numbers.get(i) < pivot){
lower.add(numbers.get(i));
}
else{
higher.add(numbers.get(i));
}
}
// Makes things go all squirrrrrrrrely
final List<Integer> notYetSorted = lower;
notYetSorted.add(pivot);
notYetSorted.addAll(higher);
System.out.println("During: " + notYetSorted);
// -------------
final List<Integer> sorted = quicksort(lower);
sorted.add(pivot);
sorted.addAll(quicksort(higher));
return sorted;
}
public static void main(String[] args) {
List<Integer> intList = new ArrayList<>();
intList.add(5);
intList.add(8);
intList.add(2);
intList.add(9);
intList.add(10);
intList.add(3);
intList.add(4);
intList.add(7);
intList.add(1);
intList.add(6);
System.out.println("Before: " + intList);
System.out.println("After: " + quicksort(intList).toString());
}
}
答案 0 :(得分:5)
您的问题出现在此块的开头:
final List<Integer> notYetSorted = lower;
notYetSorted.add(pivot);
notYetSorted.addAll(higher);
System.out.println("During: " + notYetSorted);
// -------------
final List<Integer> sorted = quicksort(lower);
与C ++不同,当您将新变量分配给现有变量时,Java不会执行深层复制。因此,notYetSorted
和lower
实际上会在内存中引用完全相同的列表 - 您对notYetSorted
所做的任何更改也会转到lower
。
因此,在该块的最后一行中,您始终使用与您开始时相同大小的List
调用快速排序。这就是为什么它会永远地复存。
将第一行更改为:
final List<Integer> notYetSorted = new ArrayList<>(lower);
一切都应该好。