C++ 快速排序是Seg断层作用

C++ 快速排序是Seg断层作用,c++,segmentation-fault,quicksort,C++,Segmentation Fault,Quicksort,有人能告诉我为什么这是seg断层吗?我在一本计算机科学书中实现了这一点,但我并不擅长调试递归。我只是不知道从哪里开始调试 template<class ItemType> void sortFirstMiddleLast(ItemType arr, unsigned int first, unsigned int mid, unsigned int last) { if (arr[first] > arr[mid]) { swap(arr[first], arr[mid

有人能告诉我为什么这是seg断层吗?我在一本计算机科学书中实现了这一点,但我并不擅长调试递归。我只是不知道从哪里开始调试

template<class ItemType>
void sortFirstMiddleLast(ItemType arr, unsigned int first, unsigned int mid, unsigned int last)
{
    if (arr[first] > arr[mid]) { swap(arr[first], arr[mid]); }
    if (arr[mid] > arr[last]) { swap(arr[mid], arr[last]); }
    if (arr[first] > arr[mid]) { swap(arr[first], arr[mid]); }
}

template<class ItemType>
int partition(ItemType* arr, unsigned int first, unsigned int last)
{
    unsigned int mid = first + (last - first) / 2;
    sortFirstMiddleLast(arr, first, mid, last);
    swap(arr[mid], arr[last - 1]);
    unsigned int pivotIndex = last - 1;
    ItemType pivot = arr[pivotIndex];

    unsigned int indexFromLeft = first + 1;
    unsigned int indexFromRight = last - 2;
    cout << indexFromLeft << endl;
    cout << indexFromRight << endl;

    bool sorted = false;

    while (!sorted)
    {
        while (arr[indexFromLeft] < pivot) { indexFromLeft += 1; }
        while (arr[indexFromRight] > pivot) { indexFromRight -= 1; }

        if (indexFromLeft < indexFromRight)
        {
            swap(arr[indexFromLeft], arr[indexFromRight]);
            indexFromLeft += 1;
            indexFromRight -= 1;
        }
        else { sorted = true; }
    }

    swap(arr[pivotIndex], arr[indexFromLeft]);
    pivotIndex = indexFromLeft;

    return pivotIndex;
}

template<class ItemType>
void quickSort(ItemType* arr, unsigned int first, unsigned int last)
{
    // Create the partition: S1 | pivotIndex | S2
    int pivotIndex = partition(arr, first, last);

    // Sort subarrays S1 and S2
    quickSort(arr, first, pivotIndex - 1);
    quickSort(arr, pivotIndex + 1, last);
} // end quickSort

int main()
{
    string* a = new string[27];
    a[0] = "B";
    a[1] = "Z";
    a[2] = "Y";
    a[3] = "X";
    a[4] = "W";
    a[5] = "V";
    a[6] = "U";
    a[7] = "T";
    a[8] = "S";
    a[9] = "R";
    a[10] = "Q";
    a[11] = "P";
    a[12] = "O";
    a[13] = "N";
    a[14] = "M";
    a[15] = "L";
    a[16] = "K";
    a[17] = "J";
    a[18] = "I";
    a[19] = "H";
    a[20] = "G";
    a[21] = "F";
    a[22] = "E";
    a[23] = "D";
    a[24] = "C";
    a[25] = "B";
    a[26] = "A";
    quickSort(a, 0, 26);
    for (int i = 0; i < 26; i++)
        cout << a[i] << " ";
    cout << endl;

    return 0;
};

递归中没有基本情况。如果您的代码在执行实际工作时没有崩溃,至少它会陷入无限递归中

递归的原理是逐渐将问题简化为更小的问题,直到得到一个不需要递归就能解决的小问题:基本情况。在您的情况下,当要排序的子数组的长度小于或等于3时。在这种情况下,只需调用sortFirstMiddleLast函数,就可以对子数组进行简单的排序


特别是,您的分段错误来自indexFromRight=last-2变为负数,从而引发下溢。这是因为当要排序的子数组变小时,逻辑不再工作。但是,如前所述:不需要它工作,只需在没有分区和递归的情况下实现这些琐碎的情况。

如果你能确定这个程序应该只在一看到就工作,那么你就是优秀的。说真的,在调试器下运行你的程序……当你的last是27并且你的数组在0..26之间是不灵活的时,任何与[last]相关的东西都不是好兆头。在大门外,您运行三个交换例程的中间值,该例程可以写入arr[last],并将其作为27传递给调用方,从而调用未定义的行为。如果这不是唯一发生这种情况的地方,我一点也不会感到惊讶;我一看到这个就不看了。很公平@PaulMcKenzie。已编辑。@WillLuce字符串是什么?我假设它是std::string。@WhozCraig我编辑它以26作为最后一个传入。仍然是seg故障,但感谢您的输入。我也不会再看那里了。我已经搞乱这件事有一段时间了,我只是在寻找更多的眼睛。