c++ - C++ 大数快速排序堆栈溢出

标签 c++ sorting stack quicksort

美好的一天 我正在尝试对 10000 个数字使用快速排序,但它给了我堆栈溢出错误。它适用于随机数,但不适用于降序和升序数字。

' 谢谢

void quickSort(long* array, long start, long last)
{
    if (start < last)
    {
        int p = partition(array, start, last);
        quickSort(array, start, p-1);
        quickSort(array, p + 1, last);
    }
}
int partition(long* array, long start, long last)//first partition
{
    int j = start + 1;
    for (long i = start + 1;i <= last;i++)
    {
        if (array[i] < array[start])
        {
            swap(array[i], array[j]);
            j++;
        }           

    }
    swap(array[start], array[j - 1]);
    return j - 1;
}
'

最佳答案

对于已排序的元素,可以通过选择 array[start]array[last]array[( 三个元素的中位数来避免此问题start + last + 1)/2] 作为您的枢轴值。

int median_of_3(long* array, long start, long last)
{
    long a = (start + last + 1)/2, b = start, c = last;
    if (array[c] < array[a]) swap(array[c], array[a]);
    if (array[b] < array[a]) swap(array[b], array[a]);
    if (array[c] < array[b]) swap(array[c], array[b]);
    return partition(array, start, last);
}

避免大堆栈深度的另一种策略是计算哪个分区较小,并递归调用较小的分区。然后可以将另一个分区优化为循环(尾递归优化)。

void quickSort(long* array, long start, long last)
{
    if (start >= last) return;

    int p = median_of_3(array, start, last);
    int next_start[2] = { start, p + 1 };
    int next_last[2] = { p - 1, last };
    bool i = p > (start + last)/2;
    quickSort(array, next_start[i], next_last[i]);
    /*
     * If the compiler does not optimize the tail call below into
     * a loop, it is easy to do the optimization manually.
     */
    quickSort(array, next_start[!i], next_last[!i]);
}

自省(introspection)也可以用来避免大的堆栈深度。您跟踪递归调用深度,如果它“太深”,您将无法安全地使用不同的排序策略,例如合并排序或堆排序。这是 std::sort 当前使用的行为。

void introSortImpl(long* array, long start, long last, int depth)
{
    if (--depth == 0) {
        heapSort(array, start, last);
        return;
    }

    if (start >= last) return;

    int p = median_of_3(array, start, last);
    int next_start[2] = { start, p + 1 };
    int next_last[2] = { p - 1, last };
    bool i = p > (start + last)/2;
    introSortImpl(array, next_start[i], next_last[i], depth);
    introSortImpl(array, next_start[!i], next_last[!i], depth);
}

void introspectionSort(long* array, long start, long last)
{
    introSortImpl(array, start, last, log2(start - last) * 3);
}

关于c++ - C++ 大数快速排序堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37288359/

相关文章:

c++ - 如何静音/取消静音 BASS?

c++ - 通过引用线程对象传递取消引用的 `this` 指针,在函数对象构造函数中创建线程是好是坏?

java - 合并 K 个排序数组

java - Java 中集合的浅拷贝

python - 如何安装 pythonds 模块?

c++ - undefined reference

c++ - 在如此简单的示例中调试断言失败

algorithm - 使用哪种多标准排序算法?

c# - 以编程方式对开始菜单进行排序

java - 为什么没有办法得到堆栈的实际大小?