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
相关产品推荐
相关产品推荐

