开发者

Inconsistent Quicksort StackOverflowError

I'm working on a quicksort problem for arrays of only increasing integers. The pivot choice in this routine is always the first element of the subarray (as dictated by the problem), and at a certain point I expected this to cause a StackOverflowError. The weird thing is, it doesn't work for problems of size n = ~25,000 thru ~404,300, but it works for n much greater than that. Even when I seed the input of the array, it fluctuates to sometimes working for n = 10,000 and sometimes not working.

Here are some results I got (the time is in seconds):

10,000: .077

20,000: .282

~25,000 - ~404,300: SOE

405,000 - 3.169

410,000 - 1.632

450,000 - .098

500,000 - .059

5,000,000 - .634

10,000,000 - 1.337

100,000,000 - 18.613

Any ideas what would cause this? Code below.

Thanks in advance.

public static void main(String[] args) {
    int arraySize = 1000000;
    int[] a = new int[arraySize];
    Random gen = new Random();

    gen.setSeed(0);
    a[0] = gen.nextInt(arraySize * 10);
    for (int i = 1; i < arraySize; i++) {
        a[i] = a[i - 1] + gen.nextInt(arraySize / 10);
}


private static void quickSort(int[] a, int lo, int hi) {
    if (hi <= lo) return;
    int j = partition(a, lo, hi);
    quickSort(a, lo, j - 1);
    quickSort(a, j + 1, hi);
}

private static int partition(int[] a, int lo, int hi) {
    int i = lo, j = hi + 1;
    int pivot = a[i];
    while (true) {
        while (a[++i] > pivot) if (i == hi) break;
        while (pivot > a[--j]) if (j == lo) break;
        if (i >= j) break;
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
    开发者_开发技巧int temp = a[lo];
    a[lo] = a[j];
    a[j] = temp;
    return j;
}


I think your partition method is incorrect (but I can be wrong, I've only skimmed the code), so the data is not partitioned correctly resulting in many more recursive calls causing the stack to overflow.

I would suggest you add a print line to the quicksort method which prints out its arguments so you can convert it to a graph of lines, where the X value is the invocation number (i.e. line 1 is for the first call, line 2 is for the next call etc), and a line is drawn (X, Y1)-(X,Y2) where Y1 is the first value, and Y2 is the second.

My guess is that you will very easily now see what goes wrong (perhaps lower the amount to sort).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜