与Hoare分区的Quicksort

时间:2018-03-21 15:16:12

标签: c++ algorithm sorting

我在阅读维基百科的文章后,已经用C ++实现了一个快速排序。只是试图从学校恢复记忆,为工作变化做准备。

这是我的实施

#include <vector>

size_t partition(std::vector<int> & inputs, size_t leftIndex, size_t rightIndex)
{
    int pivotValue = inputs[leftIndex];
    size_t i = leftIndex - 1;
    size_t j = rightIndex + 1;

    while (true)
    {
        while (inputs[++i] < pivotValue);
        while (inputs[--j] > pivotValue);

        if (i >= j)
        {
            return j;
        }

        std::iter_swap(inputs.begin() + i, inputs.begin() + j);
    }

    return 0;
}

void sort(std::vector<int> & inputs, size_t leftIndex, size_t rightIndex)
{
    if (leftIndex < rightIndex)
    {
        size_t pivot = partition(inputs, leftIndex, rightIndex);
        sort(inputs, leftIndex, pivot);
        sort(inputs, pivot + 1, rightIndex);
    }
}

int main()
{
    std::vector<int> inputs = { 3,7,1,2,9,5,4,0,8,6 };
    sort(inputs, 0, inputs.size() - 1);

    return 0;
}

对于我迄今为止提出的所有测试输入似乎都运行正常。

为了清晰起见,从这里进行编辑

如果我们改变

        if (i >= j)
        {
            return j;
        }

        if (i > j)
        {
            return j;
        }
        else if(i == j)
        {
            return j;
        }

我的问题是,什么样的输入会运行以下分区函数块?

        if (i > j)
        {
            return j;
        }

2 个答案:

答案 0 :(得分:0)

break的正文中没有while (true) { ... },因此无法访问其中的任何内容。

当您的测试用例运行完成,并且没有抛出或捕获的异常时,这意味着他们必须每次所有点击return j; partition编辑。

答案 1 :(得分:0)

出现了混乱,因为我实施了错误的算法。正如一些用户在原始问题的评论中指出的那样(在编辑之前),维基百科上的列表使用do / while而不是while,这样i的增量和j的减少在评估条件之前发生

我认为没有功能差异,但有。

所以,给定一个等效的分区函数:

size_t partition(std::vector<int> & inputs, size_t leftIndex, size_t rightIndex)
{
    int pivotValue = inputs[leftIndex];
    size_t i = leftIndex - 1;
    size_t j = rightIndex + 1;

    while (true)
    {
        while (inputs[++i] < pivotValue);
        while (inputs[--j] > pivotValue);

        if (i >= j)
        {
            return j;
        }

        std::iter_swap(inputs.begin() + i, inputs.begin() + j);
    }

    return 0;
}

很明显,对于i&gt; = j的检查将在循环走向每个边界更靠近中间的标记之后获得真正的命中,当它们指向相同的元素或相互交叉时。 / p>

使用修正递增和递减循环,主循环的每次迭代都会发生递增和递减。而在此之前,他们没有。

与往常一样,在处理算法时,请在纸上逐步完成,然后就会变得清晰。