已解决:我正在使用每次递归调用实例化一个新的Random对象。我把它作为Quicksort的一个静态变量,现在它完全正常。
我正在用Java编写Quicksort作为学校作业,但我陷入困境。我正在使用nextInt()
类中的Random
方法随机选择枢轴。这意味着我在每个递归步骤中调用nextInt()
。
我的quicksort在具有20000个元素的数组中完美地完成了工作。但是当我尝试使用40000个元素对数组进行排序时,会出现StackOverflowError
java.lang.StackOverflowError: null (in java.util.Random)
我在谷歌搜索此错误购买没有任何帮助我。我的猜测是我用完了随机的内容,但我在java中非常棒,我甚至没有自己的猜测。
这是我的代码(西班牙语是我的第一语言,对于蹩脚的英语和西班牙语代码感到抱歉)
public static void quicksort(String[] A, int min, int max){// llamar ord(A, 0, n-1);
if(min >= max){
return;
}
Random rand = new Random();
int pivote = particionar(A, min, max, rand);
quicksort(A, min, pivote-1);
quicksort(A, pivote + 1, max);
}
public static int particionar(String[] A, int min, int max, Random rand){
int menores = min + 1;
int mayores = max;
int pivote = rand.nextInt(max-min+1) + min;
String pivotstr = A[pivote];
//dejar pivote al principio
String aux = A[min];
A[min] = A[pivote];
A[pivote] = aux;
while(menores <= mayores){
if(A[menores].compareTo(pivotstr) <= 0){
menores++;
}
else{//intercambiar
String aux2 = A[menores];
A[menores] = A[mayores];
A[mayores] = aux2;
mayores--;
}
}
//mover pivote donde corresponde
String aux3 = A[min];
A[min] = A[mayores];
A[mayores] = aux3;
return mayores;
}
答案 0 :(得分:0)
当您的递归运行得太深时,就会得到StackOverflowError。
解决方案:将其转换为迭代版本。 Way to go from recursion to iteration
答案 1 :(得分:0)
您的程序生成了太多级别的递归调用和堆栈内存不足。一种解决方案是在运行时增加堆栈大小,如here所述。另一种是根据lorenzo.marcon的建议将递归转换为迭代。
Java的默认随机数生成器是一个具有48位种子大小的线性同余生成器,因此它的循环长度应为2 ** 48。这意味着你不会用完随机数,而是在那么多值之后重复序列。
堆栈溢出问题的一个重要原因是您在每次递归调用时都要实例化一个新的Random对象。每次想要喝水时都不会挖新井,大多数人会挖一口井并重新检查它以获得更多的水。类似地,推荐的做法是实例化一个静态Random对象并重新访问它以获得更多值,除非你真的知道你在做什么 - 你几乎从不想要多个Random对象。