快速排序调试

quicksort debug

本文关键字:调试 快速排序      更新时间:2023-10-16

有人能指出为什么快速排序的实现不起作用吗?我已经看了好几次了,似乎找不到错误

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);
    }
}

对快速排序的调用只是

myQuickSort(anArray,0,size-1);

Methinks

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

应该在for循环之外。

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

就我个人而言,我无法正确地思考您正在使用的抽象:我可以更容易地思考迭代器指向相应的对象,并找到下一个要交换的对象也应该是函数。此外,我需要把事情分解成小的、可理解的部分。您可以在某个时刻交换对象。这应该是一个单独的功能。这个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():它不使用普通的快速排序,而是一种变体,它可以检测到它遇到了坏情况,并在这种情况下使用std::heap_sort()来保证它保持O(n log n)。