随机 QuickSort IndexOutOfBounds 异常 [duplicate]

Randomized QuickSort IndexOutOfBounds exception [duplicate]

提问人:Roo 提问时间:8/26/2021 最后编辑:talexRoo 更新时间:8/26/2021 访问量:49

问:

这是我想出的 QuickSort Randomized,但它不断抛出 IndexOutOfBounds 异常。我能得到一些帮助吗?谢谢!

import java.util.Random;

public class QuickSort {

    void quickSort(int[] A, int start, int end) { // Initially: start = 0, end = n-1
        while (start < end) {
            int iOfPartition = randomisedPartition(A, start, end);
            if (iOfPartition - start < end - iOfPartition) {
                quickSort(A, start, iOfPartition - 1);
                start = iOfPartition + 1;
            } else {
                quickSort(A, iOfPartition + 1, end);
                end = iOfPartition - 1;
            }
        }
    }

    int randomisedPartition(int[] A, int start, int end) {
        Random rng = new Random();
        int randomNum = rng.nextInt(end + 1 - start) + start;
        swap(A, A[randomNum], A[start]);
        return hoarePartition(A, start, end);
    }

    int hoarePartition(int[] A, int start, int end) {
        int pivot = A[start];
        int i = start;
        int j = end;
        while (i < j) {
            while (A[i] <= pivot && i < end) i++;
            while (A[j] > pivot && j > start) j--;
            if (i < j) swap(A, A[i], A[j]); 
        }
        swap(A, A[start], A[j]);
        return j; 
    }

    void swap(int[] A, int i, int j) {
        int temp = A[i];
        A[i] = A[j];
        A[j] = temp;
    }
}

我不断收到 arrayindexoutofbounds 错误。

Java 随机 快速排序 数组索引outofboundsexception

评论

0赞 Richard Stokes 8/26/2021
您能否分享异常的堆栈跟踪以及对每个函数的作用的评论会有所帮助
1赞 Bart 8/26/2021
我宁愿给你一根鱼竿而不是一条鱼。我知道这是某种学习过程,因为通常你永远不会为已经实现多年(并且工作正常)的东西编写自己的代码。由于 qsort 本质上是递归的,因此您需要做的就是在 quickSort 方法的开头调试或写入某个地方(通过 system.out.println 或其他方式)后续调用。您将立即看到小于零或大于数组长度的值,因为这就是此异常的全部内容。祝你好运!
0赞 500 - Internal Server Error 8/26/2021
在 中,应从 开始,而不是 - 是枢轴槽。此外,s 可以终止 if 和 cross(meet)。hoarePartition()istart+1startstartwhileij
0赞 Roo 8/27/2021
@500-InternalServerError感谢大家,但在这里我认为 i=start+1 无关紧要?因为我的 A[i] <= pivot 已经,所以 start+1 只是意味着 A[i]<pivot,这是一回事。如果我错了,请纠正我
0赞 500 - Internal Server Error 8/27/2021
@Roo:你说得对。第一个比较,在 和 之间是多余的,但这没什么大不了的。pivotA[start]

答:

0赞 Gonen I 8/26/2021 #1

我赞同上面评论的观点,你应该学会使用调试器或打印语句来尝试拼凑正在发生的事情。

尽管如此,我还是忍不住去调查。

在交换电话中查看您正在做什么。您正在取位于 randomNum 位置的值 A[randomNum]

    swap(A, A[randomNum], A[start]); // incorrectly indexing here

但是在交换中,您正在重复该过程,并获取不一定存在的 A[A[randomNum]] 处的值。

int temp = A[i]; // indexing here again

所以你的问题是你错误地索引了两次。您应该只在 swap 函数中使用 [],而不是在 randomisedPartition 函数中使用 []。randomisedPartition 应该发送交换索引,而不是索引值。

我是怎么弄清楚的? 我尝试使用非常简单的数据进行通话

int data[] = {5,3,4};
new Example().quickSort(data, 0, 2);

并得到索引越界 5 错误。这就是你调试的方式。

评论

1赞 Roo 8/27/2021
是的,谢谢你。这个错误是因为最初我将函数 swap 定义为 swap(int i, int j),而没有意识到我需要 swap(int[]A, int i, int j) 来编辑数组本身。然后我方便地忽略了交换功能,因为我愚蠢地认为它是次要的。脸掌我是使用 IntelliJ 和一般编程的新手,但下次会学习如何正确调试,如果您有任何调试技巧,我将不胜感激,感谢您的帮助!:)
0赞 Gonen I 8/27/2021
任何调试技巧?别让我开始,我有一百万个。:)基本上,这一切都是从故障点开始,然后从那里进行回溯。最小化数据,例如,像我一样从一个小数组开始。然后看看异常。如果在 Example.swap(Example.java:39) 上显示 IndexOutofBounds[5],则转到该行并打印所有变量以查看哪一个是 5。然后你会想,好吧,我是怎么来到这里的?谁把 5 人送到那里?转到调用函数,并在那里打印语句(如果使用调试器,则为断点)。快乐学习:)