递归调用溢出堆栈

时间:2015-02-21 20:52:39

标签: java arrays recursion quicksort

我在尝试实现Quicksort算法时遇到分区问题。我的实现适用于大小为10,000的数组,但是我得到了StackOverflowError。请注意,这仅在输入数组按降序排列时才会发生。随机排序的数组在导致相同问题之前最多可达10,000,000,000。

我非常确定在我对数组进行分区时,该部分出现了问题,但我无法真正看出错误。我已经尝试过调试,但找不到问题却没有成功。我知道错误是由太多的递归调用引起的,但据我所知,如果分区得到很好的实现,堆栈不应该溢出。

提前致谢:)

我的代码:

public void sort(int[] v, int first, int last) {


    if (first >= last) return; 
    //less than two elements left in subvector

    // Partition the elements so that every number of
    // v[first..mid] <= p and every number of v[mid+1..last] > p.
    int[]subvector = new int[2];

    subvector = partition(v, first, last);

    sort(v, first, subvector[0]-1);
    sort(v, subvector[1], last);

}

分区方法:

private int[] partition(int[] v, int first, int last) {
    int low = first;
    int mid = first;
    int high = last;
    int pivot = getPivot(v, last);


    while (mid <= high) {
        // Invariant:
        //  - v[first..low-1] < pivot
        //  - v[low..mid-1] = pivot
        //  - v[mid..high] are unknown
        //  - v[high+1..last] > pivot
        //
        //       < pivot   = pivot      unknown     > pivot
        //     -----------------------------------------------
        // v: |          |          |a            |           |
        //     -----------------------------------------------
        //     ^          ^          ^           ^           ^
        //    first      low        mid         high        last
        //
        int a = v[mid];
        if (a < pivot) {
            v[mid] = v[low];
            v[low] = a;
            low++;
            mid++;
        } else if (a == pivot) {
            mid++;
        } else { // a > pivot
            v[mid] = v[high];
            v[high] = a;
            high--;
        }
    }

    return new int[]{low, high};
}

1 个答案:

答案 0 :(得分:2)

Quicksort被称为O(n ^ 2)最坏的情况,即当你给它排序的输入并选择最差的枢轴(最高或最低元素)。正如您所看到的那样,这也会产生非常深的递归效果。你不包括你的枢轴选择机制,所以我不能确定你在做什么,但你似乎选择了最后一个元素。一些谷歌搜索将对qsort的枢轴选择进行广泛的讨论。