编程语言
首页 > 编程语言> > java-已排序数组的QuickSort堆栈溢出(适用于其他数据集)

java-已排序数组的QuickSort堆栈溢出(适用于其他数据集)

作者:互联网

因此,我尝试使用三个值的中位数作为枢轴,并针对较小的分区大小使用插入排序,以优化我的Quicksort算法,使其尽可能高效地运行,甚至对于排序或几乎排序的数组也是如此.我已经为大型随机值数组测试了我的代码,并且可以正常工作,但是当我通过已经排序的数组时,我会得到一个堆栈溢出错误(ironic,因为它导致我找到了这个网站).我相信这对我的递归调用是个问题(我知道分区至少适用于其他数据集),但是我不太清楚要更改什么.

这是我第一学期数据结构课程的一部分,因此任何代码审查也将有所帮助.谢谢.

public void quickSort(ArrayList<String> data, int firstIndex, int numberToSort) {
    if (firstIndex < (firstIndex + numberToSort - 1))
        if (numberToSort < 16) {
            insertionSort(data, firstIndex, numberToSort);
        } else {
            int pivot = partition(data, firstIndex, numberToSort);
            int leftSegmentSize = pivot - firstIndex;
            int rightSegmentSize = numberToSort - leftSegmentSize - 1;
            quickSort(data, firstIndex, leftSegmentSize);
            quickSort(data, pivot + 1, rightSegmentSize);
        }
}



public int partition(ArrayList<String> data, int firstIndex, int numberToPartition) {
    int tooBigNdx = firstIndex + 1;
    int tooSmallNdx = firstIndex + numberToPartition - 1;

    String string1 = data.get(firstIndex);
    String string2 = data.get((firstIndex + (numberToPartition - 1)) / 2);
    String string3 = data.get(firstIndex + numberToPartition - 1);
    ArrayList<String> randomStrings = new ArrayList<String>();
    randomStrings.add(string1);
    randomStrings.add(string2);
    randomStrings.add(string3);
    Collections.sort(randomStrings);
    String pivot = randomStrings.get(1);
    if (pivot == string2) {
        Collections.swap(data, firstIndex, (firstIndex + (numberToPartition - 1)) / 2);
    }
    if (pivot == string3) {
        Collections.swap(data, firstIndex, firstIndex + numberToPartition - 1);
    }
    while (tooBigNdx < tooSmallNdx) {
        while ((tooBigNdx < tooSmallNdx) && (data.get(tooBigNdx).compareTo(pivot) <= 0)) {
            tooBigNdx++;
        }
        while ((tooSmallNdx > firstIndex) && (data.get(tooSmallNdx).compareTo(pivot) > 0)) {
            tooSmallNdx--;
        }
        if (tooBigNdx < tooSmallNdx) {// swap
            Collections.swap(data, tooSmallNdx, tooBigNdx);
        }
    }
    if (pivot.compareTo(data.get(tooSmallNdx)) >= 0) {
        Collections.swap(data, firstIndex, tooSmallNdx);
        return tooSmallNdx;
    } else {
        return firstIndex;
    }
}

解决方法:

在您的分区方法中,有时会使用超出范围的元素:

String string1 = data.get(firstIndex);
String string2 = data.get((firstIndex + (numberToPartition - 1)) / 2);
String string3 = data.get(firstIndex + numberToPartition - 1);

(firstIndex(numberToPartition-1))/ 2不是中间元素的索引.那将是(firstIndex(firstIndex(numberToPartition-1)))/ 2

= firstIndex((numberToPartition-1)/ 2).

实际上,如果firstIndex> n / 2(其中n是输入中的元素数)正在使用索引小于firstIndex的元素.对于排序数组,这意味着您选择firstIndex处的元素作为枢轴元素.因此,您可以获得递归深度

,

对于足够大的输入,这会导致堆栈溢出.

标签:data-structures,stack-overflow,quicksort,java,algorithm
来源: https://codeday.me/bug/20191120/2043878.html