简体   繁体   English

快速排序算法引发StackOverflowException

[英]Quicksort Algorithm throws StackOverflowException

For a homework assignment, I have to write an implementation of the QuickSort algorithm and use this to sort a list with 100k numbers in some random order. 对于家庭作业,我必须编写一个QuickSort算法的实现,并使用该算法以某种随机顺序对具有100k数字的列表进行排序。

In the first part of the assignment, I have to use the first item of the array as the pivot element. 在作业的第一部分中,我必须使用数组的第一项作为枢轴元素。 This indeed returns a sorted list. 实际上,这将返回一个排序列表。 However, for the second part of the assignment I have to use the last item as the pivot, which results in a StackOverflowException. 但是,对于作业的第二部分,我必须使用最后一项作为枢轴,这会导致StackOverflowException。 When I try it in a smaller collection of 8 records, it DOES work correctly. 当我尝试在8个记录的较小集合中尝试时,它确实可以正常工作。 I've been looking at my code but I can't figure out where I'm making a mistake. 我一直在看我的代码,但我不知道自己在哪里出错。 Any help would be greatly appreciated. 任何帮助将不胜感激。 My code is as follows: 我的代码如下:

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

}

提示:如果right == left + 1会发生什么?

These two lines look fishy: 这两行看起来很混乱:

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

Look at what partition returns and compare it to how you use its result. 查看返回的partition ,并将其与使用其结果的方式进行比较。

Along with the fact that David Harkness pointed out, there are problems with the partition logic. 除了David Harkness指出的事实之外,分区逻辑也存在问题。 Try this out: (after removing things pointed by David Harkness) 尝试一下:(删除David Harkness指出的内容之后)

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

It will work for case when pivot is last element. 适用于枢轴是最后一个元素的情况。 Not for First element. 不适用于第一个元素。

Read, understand the working on paper, dry run things out, write pseudo code and then say hello to Eclipse. 阅读,理解纸上的工作,干点事,编写伪代码,然后向Eclipse打招呼。 Dont hurry to implement things. 不要着急执行事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM