快速调试

时间:2012-01-06 21:51:49

标签: c++ quicksort

任何人都可以指出为什么这种快速排序的实现不起作用,我经历过几次并且似乎无法找到错误

int quickPartition ( int data[], int p, int r)
{
    int x=data[r];
    int i=p-1;
    for (int j=p; j<r; j++)
    {
        if(data[j]<x)
        {
            i++;
            int temp=data[i];
            data[i]=data[j];
            data[j]=temp;
        }
        int temp=data[i+1];
        data[i+1]=data[r];
        data[r]=temp;   
    }
    i++;
    cout<<"i:"<<i<<endl;
    return i;
}

void myQuickSort(int data[], int left, int right)
{       
    if(left<right)
    {
        int q=quickPartition(data,left,right);
        myQuickSort(data,left,q-1);
        myQuickSort(data,q+1,right);
    }
}

对quicksort的调用只是

myQuickSort(anArray,0,size-1);

2 个答案:

答案 0 :(得分:2)

依吾

    int temp=data[i+1];
    data[i+1]=data[r];
    data[r]=temp;

应该超出for循环。

答案 1 :(得分:1)

你的分区实现看起来完全是假的。你想要的是从两端迭代,并在每一端找到属于相对部分的对象。如果迭代器相遇,那么你就完成了。否则,你交换两个对象并找到下一对。

就个人而言,我在你正在使用的抽象中无法正确思考:我更容易思考指向各个对象的迭代器,并且发现交换的下一个对象也应该是函数。此外,我需要将事物分解为小的,易于理解的位。你在某个时候交换对象。这应该是一个单独的功能。使用这个partition()看起来像这样:

int* partition(int* left, int* right, int value) {
    while (left != right)
    {
         left = find_forward(left, right, value);
         right = find_backward(left, right, value);
         if (left != right)
         {
             swap(left, right);
         }
    }
    return left;
}

我没有对此进行测试,但这些内容应该有效。显然,我只需使用std::swap()来交换元素,使用std::find_if()来查找合适的位置(对于使用std::reverse_iterator的后向案例)。好吧,如果这不是一个家庭作业,你只需要使用std::sort():它不使用vanilla快速排序,而是使用变体来检测它是否遇到了坏情况并使用了{{1}在这种情况下,要保证它保持为O(n log n)。