即使将大型数组移到堆后,C ++未知的堆栈也会溢出

问题描述

我正在计算快速排序的分区函数用于增加n个数组大小的比较次数,但遇到了问题。当我们输入sortFirstMiddleLast函数时,我遇到了堆栈溢出和Mem Access Violation错误。我在堆中创建了要排序的数组,并且在另一个递归函数调用的迭代中调用了该函数,但是递归调用应该终止,并且在第一次迭代时抛出异常。

//QuickSort Algorithm using the middle element of the array as the pivot

#include <iostream>
#include <ctime>

using namespace std;

void sortFirstMiddleLast(int*,int,int);
int partition(int*,int*);
void quickSort(int*,int*);

int main()
{
    clock_t start,stop;
    double totalTime;
    int arrSizeArr[13] = { 2,4,8,16,32,64,128,256,512,1024,2048,8192,16384 };

    for (int i = 0; i < 13; i++)
    {
        int size = arrSizeArr[i];
        int* arr = new int[size];
        
        for (int j = 0; j < size; j++)
        {
            arr[j] = (double)(size - j);
        }

        int first = 0;
        int last = size - 1;
        int* quickComp = new int(0);

        cout << "QuickSort w/ Pivot as Middle: " << endl;
        start = clock();
        quickSort(arr,first,last,quickComp);
        stop = clock();
        cout << "# of Comparisons: " << *quickComp << endl;

        totalTime = static_cast<double>(stop - start) / CLOCKS_PER_SEC;
        cout << "Run Time: " << totalTime << endl;

        delete quickComp;
        delete[] arr;
    }

    system("pause");
    return 0;
}

void quickSort(int* arr,int first,int last,int* quickComp)
{
    if (first < last)
    {
        int pivotIndex = partition(arr,quickComp);

        quickSort(arr,pivotIndex - 1,quickComp);
        quickSort(arr,quickComp);
    }
}

void sortFirstMiddleLast(int* arr,int mid,int last)
{
    int temp;

    if (arr[first] > arr[mid])
    {
        temp = arr[first];
        arr[first] = arr[mid];
        arr[mid] = temp;
    }
    if (arr[mid] > arr[last])
    {
        temp = arr[mid];
        arr[mid] = arr[last];
        arr[last] = temp;
    }
    if (arr[first] > arr[mid])
    {
        temp = arr[first];
        arr[first] = arr[mid];
        arr[mid] = temp;
    }
}

int partition(int* arr,int* quickComp)
{
    int mid = first + (last - first) / 2;
    sortFirstMiddleLast(arr,mid,last);

    int temp = arr[mid];
    arr[mid] = arr[last - 1];
    arr[last - 1] = temp;
    int pivotIndex = last - 1;
    int pivot = arr[pivotIndex];

    int indexLeft = first + 1;
    int indexRight = last - 2;

    bool done = false;
    
    while (!done)
    {
        while (arr[indexLeft] < pivot)
        {
            indexLeft++;
            *quickComp = *quickComp + 1;
        }
        while (arr[indexRight] > pivot)
        {
            indexRight--;
            *quickComp = *quickComp + 1;
        }
        if (indexLeft < indexRight)
        {
            temp = arr[indexLeft];
            arr[indexLeft] = arr[indexRight];
            arr[indexRight] = temp;

            indexLeft++;
            indexRight--;
            *quickComp = *quickComp + 1;
        }
        else
        {
            done = true;
        }
    }

    temp = arr[pivotIndex];
    arr[pivotIndex] = arr[indexLeft];
    arr[indexLeft] = temp;

    pivotIndex = indexLeft;

    return pivotIndex;
}

据我了解,使用“ new”运算符应在数组的堆上分配内存,以便随着数组大小n的增加而不会引起堆栈问题。我唯一想到的另一件事是一个非终止的递归调用,但我不明白为什么它在第一次调用时会引发异常,以及为什么它会通过quickSort和partition函数使其发生但在sortFirstMiddleLast中引发该异常。如果有人可以向我解释这一点,或者让我知道我的想法是否与众不同,我将不胜感激。Stack exception mem access exception

解决方法

在枢轴点进行分区后,此算法将pivotIndex - 1保留为两个分区中的公共元素,这是不期望的。应该是firstpivotInxex - 1,然后是pivotIndexlast。以下代码应该可以正常工作:

quickSort(arr,first,pivotIndex - 1,quickComp);
quickSort(arr,pivotIndex,last,quickComp);