C++ C++;快速排序算法不断崩溃

C++ C++;快速排序算法不断崩溃,c++,sorting,loops,recursion,quicksort,C++,Sorting,Loops,Recursion,Quicksort,尝试实现一个快速排序算法。我认为问题出在递归上,但我不知道该怎么解决它。每次我运行程序时,它都会继续崩溃,我不明白为什么。代码如下: #include<iostream> using namespace std; int pIndex; int Partition(int *A,int start,int end){ int pivot; int pIndex; if(start<end){ int pivot=A[end]; int pIndex=st

尝试实现一个快速排序算法。我认为问题出在递归上,但我不知道该怎么解决它。每次我运行程序时,它都会继续崩溃,我不明白为什么。代码如下:

#include<iostream>

using namespace std;
int pIndex;

int Partition(int *A,int start,int end){

int pivot;
int pIndex;
 if(start<end){
    int pivot=A[end];
    int pIndex=start;
    for(int x=0;x<end;x++){
        if(A[x]<A[end]){
            swap(A[x],A[pIndex]);
             pIndex=pIndex+1;   
        }   
    }
    swap(A[pIndex],A[end]);
 }
//cout<<pIndex<<endl;
swap(A[pIndex],A[end]);
return pIndex;
};
void QuickSort(int *A, int start,int end){
    if(start<end)
    {

    pIndex=Partition(A,start,end);
    QuickSort(A,pIndex+1,end);
    QuickSort(A,start,pIndex-1);
}
};
int main(){

int A[10]{4,23,1,43,2,10};  
//Partition(A,0,9);
QuickSort(A,0,5);
for(int x=0;x<10;x++){
    cout<< A[x]<<" ";
}
}
#包括
使用名称空间std;
int-pIndex;
int分区(int*A,int开始,int结束){
int轴;
int-pIndex;
如果(在本部分中开始:

int pivot;
int pIndex;
 if(start<end){
    int pivot=A[end];
    int pIndex=start;
int轴;
int-pIndex;
如果(在本部分中开始:

int pivot;
int pIndex;
 if(start<end){
    int pivot=A[end];
    int pIndex=start;
int轴;
int-pIndex;

如果(start您的分区算法的代码量大约是需要的两倍。您似乎总是选择序列中的最后一个元素作为轴心,尽管不可取,但它可以用于学术演示

你的崩溃

您正在定义两个
pIndex
值,其中只有一个是确定的。您还声明了两个
pivot
变量,但这不会导致崩溃(第一个变量从未使用过)。尽管如此,还是应该清理掉它,但代码中的丧钟是重复的
pIndex

int pivot;
int pIndex;     // HERE
if(start<end){
    int pivot=A[end];
    int pIndex=start; // HERE AGAIN
    for(int x=0;x<end;x++){
        if(A[x]<A[end]){
            swap(A[x],A[pIndex]);
            pIndex=pIndex+1;   
        }   
    }
    swap(A[pIndex],A[end]);
}
swap(A[pIndex],A[end]); // uses non-determined pIndex
return pIndex; // returns non-determined pIndex
上述算法仅包括分区所需的必要条件:序列迭代器(在您的情况下是指针)和序列长度。其他一切都是基于这两个项目确定的。下面是一个快速示例程序,其中特意为pivot值设置了5:

#include <iostream>

size_t Partition(int *A, size_t len)
{
    if (len < 2)
        return 0;

    size_t pvt = 0;
    for (size_t i=0; i<len-1; ++i)
    {
        if (A[i] < A[len-1])
            std::swap(A[i], A[pvt++]);
    }
    std::swap(A[pvt], A[len-1]);
    return pvt;
};

int main()
{
    int arr[] = { 4, 8, 7, 3, 9, 2, 1, 6, 5 };
    size_t n = Partition(arr, sizeof(arr)/sizeof(*arr));
    std::cout << "Partition : " << n << '\n';
    for (auto x : arr)
        std::cout << x << ' ';
    std::cout << '\n';
}

如何从快速排序调用

Partition : 4
4 3 2 1 5 7 8 6 9 
1 2 3 4 5 6 7 8 9 
在快速排序中调用分区将设置轴位置,该轴位置将成为底部段的“结束”迭代点,以及顶部段的迭代点之前的轴位置。它是从调用
分区()返回的轴位置
递归时不应包含在任何子序列中

void QuickSort(int *A, size_t len)
{
    if (len < 2)
        return;

    size_t pvt = Partition(A, len);
    QuickSort(A, pvt++);        // NOTE: post increment...
    QuickSort(A+pvt, len-pvt);  // ...which makes this skip the pivot
}
输出

Partition : 4
4 3 2 1 5 7 8 6 9 
1 2 3 4 5 6 7 8 9 

我希望它能有所帮助。

您的分区算法的代码量大约是所需代码量的两倍。您似乎总是选择序列中的最后一个元素作为轴心点,尽管不可取,但它可以用于学术演示

你的崩溃

您正在定义两个
pIndex
值,其中只有一个是确定的。您还声明了两个
pivot
变量,但这不会导致崩溃(第一个变量从未使用过)。尽管如此,还是应该清理掉它,但代码中的丧钟是重复的
pIndex

int pivot;
int pIndex;     // HERE
if(start<end){
    int pivot=A[end];
    int pIndex=start; // HERE AGAIN
    for(int x=0;x<end;x++){
        if(A[x]<A[end]){
            swap(A[x],A[pIndex]);
            pIndex=pIndex+1;   
        }   
    }
    swap(A[pIndex],A[end]);
}
swap(A[pIndex],A[end]); // uses non-determined pIndex
return pIndex; // returns non-determined pIndex
上述算法仅包括分区所需的必要条件:序列迭代器(在您的情况下是指针)和序列长度。其他一切都是基于这两个项目确定的。下面是一个快速示例程序,其中特意为pivot值设置了5:

#include <iostream>

size_t Partition(int *A, size_t len)
{
    if (len < 2)
        return 0;

    size_t pvt = 0;
    for (size_t i=0; i<len-1; ++i)
    {
        if (A[i] < A[len-1])
            std::swap(A[i], A[pvt++]);
    }
    std::swap(A[pvt], A[len-1]);
    return pvt;
};

int main()
{
    int arr[] = { 4, 8, 7, 3, 9, 2, 1, 6, 5 };
    size_t n = Partition(arr, sizeof(arr)/sizeof(*arr));
    std::cout << "Partition : " << n << '\n';
    for (auto x : arr)
        std::cout << x << ' ';
    std::cout << '\n';
}

如何从快速排序调用

Partition : 4
4 3 2 1 5 7 8 6 9 
1 2 3 4 5 6 7 8 9 
在快速排序中调用分区将设置轴位置,该轴位置将成为底部段的“结束”迭代点,以及顶部段的迭代点之前的轴位置。它是从调用
分区()返回的轴位置
递归时不应包含在任何子序列中

void QuickSort(int *A, size_t len)
{
    if (len < 2)
        return;

    size_t pvt = Partition(A, len);
    QuickSort(A, pvt++);        // NOTE: post increment...
    QuickSort(A+pvt, len-pvt);  // ...which makes this skip the pivot
}
输出

Partition : 4
4 3 2 1 5 7 8 6 9 
1 2 3 4 5 6 7 8 9 

<>我希望它有帮助。

我也是C++新手,但我发现自己对在开始>结束时发生什么感到好奇。看起来你的分区函数仍然会返回pHealk值,但是我不知道你在哪里定义它。如果(我怀疑)它返回驻留在内存中的任何值,当您使用[pIndex]时,很可能会引用一些未定义的内存位置

我也是C++新手,但我发现自己对在开始>结束时发生什么感到好奇。看起来你的分区函数仍然会返回pHealk值,但是我不知道你在哪里定义它。如果(我怀疑)它返回驻留在内存中的任何值,然后当您使用[pIndex]时,您很可能会引用一些未定义的内存位置。

您是否尝试在调试器下运行该程序?它在哪一行显示崩溃?您不应该在
后加分号
在函数末尾;它是一个null语句或null声明。但是,这与崩溃完全无关。给出的答案解决了崩溃问题,但是,我认为您必须重新审视算法的逻辑,因为分区永远不会像您所期望的那样工作。您是否尝试过在调试器下运行程序?它是哪一行是否显示崩溃?您不应该在函数末尾的
}
后面加分号;它是一个空语句或空声明。但是,这与崩溃完全无关。给出的答案解决了崩溃问题,但是,我认为您必须重新审视算法的逻辑,因为分区永远不会像您预期的那样工作。That不工作。输出为
23 10 2 43 4 1 0 0 0 0 0
(虽然它至少没有崩溃)当我在中替换此函数时,它确实修复了崩溃。但屏幕上绝对没有显示任何内容。这不工作。输出为
23 10 2 43 4 1 0 0 0 0 0
(尽管它至少没有崩溃)当我在中替换此函数时,它确实修复了崩溃。但屏幕上绝对没有显示任何内容。您观察到的
pIndex
从未设置是即时的。您观察到的
pIndex
从未设置是即时的。非常感谢,这解决了问题。我感谢您在帖子中所做的所有工作:)非常感谢你,这解决了问题。我感谢你在帖子中所做的一切:)谢谢