java - 使用快速排序对大型列表进行排序时总是会发生堆栈溢出

标签 java algorithm sorting quicksort

我正在为一项作业进行快速排序,但在对大型列表(> 100.000 个项目)进行排序时,它总是会引发堆栈溢出。堆栈溢出应该表明停止条件不正确,但我找不到问题。我真的很感激一些帮助。谢谢阅读。 我的快速排序:

private void qSort(List<E> items, int low, int high, Comparator<E> comparator) {
    // base case
    if (low >= high) {
        return;
    }

    // set the pivot (last element)
    E pivot = items.get(high);

    int leftPointer = low;
    int rightPointer = high;

    while (leftPointer < rightPointer) {
        // we move the left pointer until we find a value that is bigger than the pivot
        while (leftPointer < rightPointer && comparator.compare(items.get(leftPointer), pivot) <= 0) {
            leftPointer++;
        }

        // we move the right pointer until we find a value that is smaller than the pivot
        while (leftPointer < rightPointer && comparator.compare(items.get(rightPointer), pivot) >= 0) {
            rightPointer--;
        }

        // swap the values at the pointers
        swap(items, leftPointer, rightPointer);

    }
    // at this point, leftPointer and rightPointer are equal and we need to swap the item at the pointers with the pivot
    swap(items, leftPointer, high);

    // now we have the pivot is in the correct position
    // we continue recursively sorting the left side of the pivot, (not including the pivot, because its already in its final position)
    qSort(items, low, leftPointer - 1, comparator);
    // and the right side of the pivot
    qSort(items, leftPointer + 1, high, comparator);

}

我尝试了各种不同的实现,但没有一个有效。我尝试过增加堆栈大小。

最佳答案

如果您的数据包含已排序的运行,则 n 项的快速排序将需要 O(n) 堆栈帧。即使只有一些排序运行,这也可能是一个问题。

对此有多种解决方案。最简单的方法是在使用之前将枢轴与随机元素交换。您现在将执行 O(n) 工作来生成 O(n) 伪随机选择。但现在几乎不可能触发快速排序的潜在病态行为。

目前最常用的解决方案是使用另一种排序算法。 Timsort是一个流行的选择,因为它最坏情况的行为是 O(n log(n)),但它可以找到并利用排序序列来获得时间 O(n)在许多常见的现实世界场景中。

关于java - 使用快速排序对大型列表进行排序时总是会发生堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77470194/

相关文章:

java - "synchronized-with-resource"获取锁对象也必须同步怎么办?

Python 按相同顺序对 2 个不同的 Size 列表进行排序?

php - MySQL 中的排序/

java - 使用数组列表洗牌的输出不显示

java - 没有这样的算法 : AES for provider BC

算法 - friend 的 friend

java - Java 中的有向图处理

python - arr = [val] * N 是否具有线性或常数时间?

mysql - 通过 IN 子句对 MySQL 查询结果进行排序

java - 在 Android 上的所有应用中添加 KeyListener 和 Draw To Screen