不一致的快速排序 StackOverflowError

发布于 2024-10-20 07:41:08 字数 1442 浏览 2 评论 0原文

我正在研究仅递增整数的数组的快速排序问题。此例程中的主元选择始终是子数组的第一个元素(由问题决定),并且在某个时刻我预计这会导致 StackOverflowError。奇怪的是,它不适用于大小 n = ~25,000 到 ~404,300 的问题,但它适用于 n 比这大得多的问题。即使当我为数组的输入添加种子时,它也会波动,有时适用于 n = 10,000,有时则不适用。

以下是我得到的一些结果(时间以秒为单位):

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

有什么想法会导致这种情况吗?代码如下。

提前致谢。

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'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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

む无字情书 2024-10-27 07:41:08

我认为您的分区方法不正确(但我可能是错的,我只是浏览了代码),因此数据未正确分区,导致更多的递归调用导致堆栈溢出。

我建议您向快速排序方法添加一个打印行,该方法打印出其参数,以便您可以将其转换为线图,其中 X 值是调用号(即第 1 行用于第一次调用,第 2 行用于下一次调用等),并绘制一条线 (X, Y1)-(X,Y2),其中 Y1 是第一个值,Y2 是第二个值。

我的猜测是,您现在会很容易地看到出了什么问题(也许会降低排序的数量)。

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文