You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hoare分区交换枢轴至首部可处理的退化情况及实现疑问

关于Hoare分区实现的两个疑问

实现代码

适配重复元素场景、可支撑线性时间快速选择的Hoare分区实现代码如下:

// let x be the initial value of *pivot and k the return value; then,
// [begin, k) <= x and [k, end) >= x
template <std::random_access_iterator It>
It partition(It begin, It pivot, It end) {
    using std::ranges::iter_swap;
    iter_swap(begin, pivot);
    It i = begin;
    It j = end;
    while (true) {
        do {
            --j;
        } while (*j > *pivot);
        while (*i < *pivot) {
            ++i;
        }
        if (i < j) {
            iter_swap(i, j);
            ++i;
        } else {
            return j + 1;
        }
    }
}

分区契约:记枢轴初始值为x,函数返回分割点迭代器k,则分区完成后[begin, k)内所有元素满足<= x,[k, end)内所有元素满足>= x

疑问1:初始交换枢轴到区间首部的作用

实现作者说明,初始将枢轴交换到区间首部的操作,是避免退化分区的必要操作。我希望明确此处所指的具体退化情况/退化分区有哪些。
该实现没有采用固定枢轴逻辑,同时混用while与do-while循环结构,理解门槛较高,这也是我产生该疑问的原因。

疑问2:测试结果是否符合实现预期

我编写了如下测试代码验证该实现的行为:

void print(const int *a, const size_t len) {
    for (size_t i = 0; i < len; i++) {
        std::cout << a[i] << " ";
    }
    std::cout << std::endl;
}

int main() {
    int a[] = {1, 13, 3, 19, 5, 15, 24, 23, 9, 17, 11, 21, 7, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 0};
    constexpr auto size = sizeof a / sizeof a[0];
    print(a, size);

    std::cout << a[12] << std::endl;
    std::cout << "Element count in the 1st partition: " << partition(a, a + 12, std::end(a)) - a << std::endl;
    print(a, size);
}

代码运行输出如下:

1 13 3 19 5 15 24 23 9 17 11 21 7 2 4 6 8 10 12 14 16 18 20 22 0 
7
Element count in the 1st partition: 6
0 1 3 11 5 9 24 23 15 17 19 21 13 2 4 6 8 10 12 14 16 18 20 22 7 

本次分区选取的枢轴值为7,按照常规认知,2、4、6等小于7的元素应当被划分到枢轴左侧,我想确认当前运行结果是否符合该实现的正确预期。


内容的提问来源于stack exchange,提问作者ledonter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 10:01:47