Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 快速排序算法抛出StackOverflowException_Java_Algorithm - Fatal编程技术网

Java 快速排序算法抛出StackOverflowException

Java 快速排序算法抛出StackOverflowException,java,algorithm,Java,Algorithm,对于家庭作业,我必须编写一个快速排序算法的实现,并使用它以某种随机顺序对一个包含100k个数字的列表进行排序 在赋值的第一部分中,我必须使用数组的第一项作为枢轴元素。这确实会返回一个排序列表。然而,对于任务的第二部分,我必须使用最后一项作为轴心,这导致StackOverflowException。当我在一个包含8条记录的较小集合中尝试时,它确实可以正常工作。我一直在看我的代码,但我不知道我在哪里犯了错误。任何帮助都将不胜感激。我的代码如下: public class QuickSort {

对于家庭作业,我必须编写一个快速排序算法的实现,并使用它以某种随机顺序对一个包含100k个数字的列表进行排序

在赋值的第一部分中,我必须使用数组的第一项作为枢轴元素。这确实会返回一个排序列表。然而,对于任务的第二部分,我必须使用最后一项作为轴心,这导致StackOverflowException。当我在一个包含8条记录的较小集合中尝试时,它确实可以正常工作。我一直在看我的代码,但我不知道我在哪里犯了错误。任何帮助都将不胜感激。我的代码如下:

public class QuickSort {

    private QuickSortStrategyEnum quickSortStrategy;

    public QuickSort(QuickSortStrategyEnum quickSortStrategy) {

        this.quickSortStrategy = quickSortStrategy;
    }

    public List<Integer> sortIntegerArray(List<Integer> arrayList, int left, int right) {

        if ( left >= right ) {
            return arrayList;
        }

        int i = partition(arrayList, left, right);

        if (i <= right) {

            int pivotNew = partition(arrayList, i, right);
            int pivotIndex = arrayList.indexOf(pivotNew);

            arrayList = sortIntegerArray(arrayList, left , pivotIndex - 1);
            arrayList = sortIntegerArray(arrayList, pivotIndex + 1, right);
        }

        return arrayList;
    }

    private int partition(List<Integer> arrayList, int left, int right) {

        int pivot = getPivot(arrayList, left, right);
        int i = left + 1;

        for (int j = i; j <= right; j++) {

            if (arrayList.get(j) < pivot) {

                Collections.swap(arrayList, j, i);
                i++;
            }
        }

        Collections.swap(arrayList, left, i - 1);
        return i;
    }

    private int getPivot(List<Integer> arrayList, int left, int right) {

        int pivot = 0;

        switch (quickSortStrategy) {

            case FIRST:
            pivot = arrayList.get(left);
            break;

            case LAST:
            pivot = arrayList.get(right);
            break;
        }
        return pivot;
    }

}
公共类快速排序{
私有QuickSortStrategyEnum quickSortStrategy;
公共快速排序(快速排序策略枚举快速排序策略){
this.quickSortStrategy=quickSortStrategy;
}
公共列表排序规则(列表数组列表,左整数,右整数){
如果(左>=右){
返回数组列表;
}
int i=分区(arrayList,左,右);

if(i提示:如果
right==left+1
,会发生什么情况?

这两行看起来可疑:

int pivotNew = partition(arrayList, i, right);
int pivotIndex = arrayList.indexOf(pivotNew);

查看分区返回的内容,并将其与如何使用其结果进行比较。

以及David Harkness指出的事实,分区逻辑存在问题。请尝试:(删除David Harkness指出的内容后)

private int partition(列表arrayList,int left,int right){
int pivot=getPivot(arrayList,左,右);
int i=左-1;
对于(int j=left;j如果(arrayList.get(j)+1在调试器中单步执行代码会很有用。;)除了
分区
做大量繁忙的工作之外,我看不出这种情况有什么问题。不过,我只是在头脑中单步执行。:)知道什么方法/行引发异常会有帮助。嗯,你就在这里,现在解决了这个问题。:)不幸的是,我还没有足够的分数来投票给你。。如果左是第一个元素(0),你将索引
I
-1,这将导致
集合.swap(arrayList,j,I);
抛出一个
IndexOutOfBoundsException
。在桑德的代码中,行是
int i=left+1;
。这是一个复制粘贴错误吗?啊,你说得对:)在真正理解这个过程之前,我很快就开始尝试编写一个解决方案。现在我知道它是如何工作的,并且可以继续使用这个解决方案。我不能放弃你u不幸的是,我没有得到足够的分数,但非常感谢!@JessevanAssen注意到,在调用Collections.swap(arrayList,j,I)之前,我增加了I。我已经测试了我的代码,它可以工作了
private int partition(List<Integer> arrayList, int left, int right) {

    int pivot = getPivot(arrayList, left, right);
    int i = left - 1; 

    for (int j = left; j < right; j++) {
        if (arrayList.get(j) <= pivot) {
            i++;
            Collections.swap(arrayList, j, i);
        }
    }

    Collections.swap(arrayList, i+1, right);
    return i+1;
}