找不到quicksort bug

时间:2010-12-02 22:05:11

标签: c++ debugging sorting quicksort

在这一天工作了一整天后,我找不到我的代码有什么问题,我无法找到我的错误所在。请有人帮我弄清楚我做错了什么?

void a_quick(int array[], int i, int j){
    //Array Quick Sort
    if ((j - i) < 2){
        return;
    }
    int top = j;
    int bot = i;
    int p_location = i + (j + i) / 2;
    int pivot = array[p_location];
    while (i < j){
        while (array[i] < pivot){
            i++;
        }
        while (array[j] > pivot){
            j--;
        }
        if (i <= j){
            swap(array[i], array[j]);
            i++;
            j--;
        }
    }
    a_quick(array, bot, p_location);
    a_quick(array, p_location + 1, top);

}

在64k int数组上运行代码会使计算机崩溃,我需要让它在128k上运行。

我得到:

Test Array:
703 322 673 141 253 547 662 37 723 529 316 190 288 40 264 446 890 370 6 393

Quick Sort w Array:
6 37 40 141 253 190 316 288 264 322 393 370 446 529 723 662 890 547 673 703

7 个答案:

答案 0 :(得分:1)

一个问题是最后两行应该是:

a_quick(array, bot, p_location - 1);
a_quick(array, p_location + 1, top);

另一个问题是您需要准备好移动枢轴(并跟踪其索引)。只有在枢轴已经恰好位于正确的位置时,您的代码才会起作用,这是不可能的。

为了进行比较,请查看Wikipedia中可用的伪代码的几个版本。

答案 1 :(得分:1)

相当破碎。你需要将枢轴项移开(通常是你正在分区的数组的开头),因为一半的元素不太可能比枢轴小一半而且更大。

正如其他人所说,当你递归时,你会在两个子分区中包含枢轴。

我首先要证明一个分区运行起作用(即现在不进行递归,分区完成后停止,现在检查数组是怎么回事)

答案 2 :(得分:1)

计算枢轴的方式存在问题。问问自己当指数是5和9时会发生什么。而不是:

p_location = (j - i) / 2;

尝试更多类似的内容:

p_location = i + (j - i) / 2;

答案 3 :(得分:1)

这应该有效

void a_quick(int array[], int i, int j){
//Array Quick Sort
if (j <= i) return; // change here (j - i) < 1 (not 2)

int top = j;
int bot = i;
int p_location = (j + i) / 2; // change here - by + so you pick the middle
int pivot = array[p_location];
while (i < j){
    while (array[i] < pivot){
        i++;
    }
    while (array[j] > pivot){
        j--;
    }
    if (i <= j){
        swap(array[i], array[j]);
        i++;
        j--;
    }
}
a_quick(array, bot, j); // change here (dont use p_loc, use i and j)
a_quick(array, i, top); // and here

}

答案 4 :(得分:1)

此代码适用于我

   void a_quick(int array[], int i, int j){
    //Array Quick Sort

    int top = j;
    int bot = i;
    int p_location = (j + i) / 2;
    int pivot = array[p_location];
    do {
        while (array[i] < pivot)i++;
        while (array[j] > pivot)j--;
        if (i <= j){
            swap(array[i], array[j]);
            i++;
            j--;
        }
    } while (i<=j);
    if (bot<j) a_quick(array, bot, j);// problem is most likely here
    if (i<top) a_quick(array, i, top);// or here
}

答案 5 :(得分:0)

我试过了:

void a_quick(int array[], int i, int j){
    //Array Quick Sort
    if ((j - i) < 2){
        return;
    }
    int top = j;
    int bot = i;
    int p_location = (j - i) / 2;
    int pivot = array[p_location];
    while (i < j){
        while (array[i] < pivot){
            i++;
        }
        while (array[j] > pivot){
            j--;
        }
        if (i <= j){
            std::swap(array[i], array[j]);
            i++;
            j--;
        }
    }
    a_quick(array, bot, p_location);// problem is most likely here
    a_quick(array, p_location, top - 1);// or here
}

int main()
{
    // int d[] = { 5, 1, 6, 4, 8, 2, 3, 7, 9, 0};
    int d[] = { 5, 1, 6, 4, 8, 2, 3, 7, 0, 9};
    a_quick(d, 0, 9);

    std::copy(d, d+10, std::ostream_iterator<int>(std::cout));
}

> g++ sort.cpp
> ./a.exe
0124356789 >

它运作良好。
我们真正需要的是它失败的一个例子。

希望有一个完整的测试工具,只需编译并运行并显示错误。

答案 6 :(得分:0)

这应该有效

#include <memory>
#include <iterator>
#include <algorithm>
#include <iostream>

void a_quick(int array[], int i, int j){
    //Array Quick Sort
    if ((j - i) < 2){
        return;
    }
    int top = j;
    int bot = i;

    // Bug 1: Pick something in the correct range.
    int pivot = array[i + (j-i)/2];
    while (i < j){
        while (array[i] < pivot){
            i++;
        }
        while (array[j] > pivot){
            j--;
        }
        if (i < j)
        {
            // Bug 2: swap is in the std namespace
            std::swap(array[i], array[j]);

            // Bug 3: Don't increment the pointers.
            //        What if you hit the pivot point.
        }
    }
    // The split is not at where you selected the pivot point.
    // As that could be any number and it may not split evenly.
    // So you pick either of i or j. I picked j as the mid point
    // One sort upto j the other sorts from j+1 to the end.
    a_quick(array, bot, j );
    a_quick(array, j+1 , top );
}


int main()
{
    int d[] = { 703, 322, 673, 141, 253, 547, 662, 37, 723, 529, 316, 190, 288, 40, 264, 446, 890, 370, 6, 393 };
    int size = sizeof(d)/sizeof(d[0]);

    a_quick(d, 0, size - 1 );

    std::copy(d, d+size, std::ostream_iterator<int>(std::cout, ", "));
}