Recursive Shuffle Algo抛出StackOverflow错误

时间:2013-11-20 00:10:34

标签: java algorithm recursion shuffle

这是Fisher-Yates shuffle的递归实现。为什么当我给它输入少至10000个项目时会抛出StackOverflow错误?

public static void main(String[] args)
{
    int[] array = algo3(10000);
}

public static int[] algo3(int n)
{
    int[] a = new int[n];
    for (int i = 0; i < a.length ; i++)
        a[i] = i;
    algo3(a, 0);
    return a;
}

public static void algo3(int[] a, int pos)
{
    if (pos == a.length - 1)
        return;
    int tmp = a[pos];
    int rand = randInt(pos,a.length); // line #27
    a[pos] = a[rand];
    a[rand] = tmp;
    algo3(a,pos + 1); // line #30
}

private static int randInt(int i, int j)
{
    return (int) (Math.random() * (j - i)) + i; // line #35
}

堆栈跟踪:

Exception in thread "main" java.lang.StackOverflowError
    at java.util.concurrent.atomic.AtomicLong.compareAndSet(Unknown Source)
    at java.util.Random.next(Unknown Source)
    at java.util.Random.nextDouble(Unknown Source)
    at java.lang.Math.random(Unknown Source)
    at nl.saxion.Week1.randInt(Week1.java:35)
    at nl.saxion.Week1.algo3(Week1.java:27)
    at nl.saxion.Week1.algo3(Week1.java:30)

2 个答案:

答案 0 :(得分:4)

递归系统中的Fischer-Yates将为数组中的每个成员执行一个级别的随机播放。

堆栈溢出将在10,000级别的呼叫之前发生。

是否有一些特殊原因导致您无法使用while循环版本?它更简单,更快速,更可靠.....它是一个5线程算法....作为一个while循环。


EDIT。作为测试,我写了以下内容:

private static final void recurse(int val) {
    System.out.println(val);
    recurse(val + 1);
}
public static void main(String[] args) {
    recurse(1);
}

小心猜测我在哪里遇到溢出异常?嗯,从不!我猜我的JIT将它编译成循环而不是递归,我在'1816130'之后的某个地方杀了这个过程。

答案 1 :(得分:1)

10000是一个很大的数字,特别是因为你正在处理一个10 000个元素数组。您可以使用-Xss JVM参数来缩小堆栈的大小。