我在功能逻辑上哪里出错了

时间:2015-11-20 01:37:30

标签: c++ sorting vector quicksort

我正在编写一个程序来进行快速排序,中位数为3.我的快速排序算法在这里:

void quickSort(vector<int> & a, int left, int right) {
    if (left + 10 <= right) {
        const int & pivot = median3( a, left, right);

        int i = left, j = right -1;
        for ( ; ; ){
            while(a [++i] < pivot){}
            while(pivot < a[--j]){}
            if(i < j)
                swap(a[i], a[j]);
            else
                break;
        }
        swap(a[i], a[right-1]);

        quickSort(a,left,i-1);
        quickSort(a,i+1,right);
    }
}

我生成的矢量要排序(仅排序矢量[0])

vector<vector<int> > vectorList;

for (unsigned int j = 0; j < 8; j++) {
    vector<int> tmp(100*pow(2,j));

    for (unsigned int l = 0; l<tmp.size(); l++)
        tmp[l] = (rand() % 20000);

    vectorList.push_back(tmp);

我打电话给主要的快速通道:

quickSort(vectorList[0], 0, vectorList[0].size()-1);

我的程序当前会打印出随机值,但是实际排序值时却遇到了麻烦。我以为我有一切正确的算法明智,但显然不是。我经历过多次,无法找出问题所在。是否有任何新的眼睛可以发现问题,并就如何纠正它提供一些建议?非常感谢提前!

1 个答案:

答案 0 :(得分:2)

假设这是Hoare分区方案,而且median3可以处理1个以上元素的长度。注释中注明的原始更改。评论描述为&#34;与原始&#34;相同的逻辑;只是化妆品的变化,上面原始例子中这些行的代码逻辑没有变化。 if(left + 10&lt; = right)和j = right-1可能是唯一真正的错误,但这个例子遵循典型的Hoare分区方案风格。

快速排序的工作实现可能很棘手,因为一个小错误可能只会失败,因为特定的模式可能永远不会被测试。

void quickSort(vector<int> & a, int left, int right) {
    if(left >= right)               // left < right (not left+10 <= right)
        return;                     //  else nothing to do so return
    int pivot = median3( a, left, right);
    int i = left-1, j = right+1;    // left-1 (not left), right+1 (not right-1)
    while(1){                       // same logic as original
        while(a[++i] < pivot);      // same logic as original
        while(a[--j] > pivot);      // same logic as original
        if(i >= j)                  // same logic as original
            break;                  // same logic as original
        swap(a[i], a[j]);           // same logic as original
    }
    quickSort(a,left,j);            // use j   (not i-1)
    quickSort(a,j+1,right);         // use j+1 (not i+1)
}

示例median3

int median3(vector<int> & a, int left, int right)
    int i = left, j = (left + right)/2, k = right;
    if (a[k] < a[i])
        swap(a[k], a[i]);
    if (a[j] < a[i])
        swap(a[j], a[i]);
    if (a[k] < a[j])
        swap(a[k], a[j]);
    return(a[j]);
}

对原始示例的最小改变为典型的Hoare分区方案样式。

void quickSort(vector<int> & a, int left, int right) {
    if (left <= right) {                         // not (left+10 <= right)
        int pivot = median3( a, left, right);    // const ... & ??
        int i = left-1, j = right +1;            // left-1, right+1
        for ( ; ; ){
            while(a [++i] < pivot){}
            while(pivot < a[--j]){}
            if(i < j)
                swap(a[i], a[j]);
            else
                break;
        }
        // swap(a[i], a[right-1]);               // deleted this line
        quickSort(a,left,j);                     // j instead of i-1
        quickSort(a,j+1,right);                  // j+1 instead of i+1
    }
}