`std::partition()` 的时间复杂度

Posted

技术标签:

【中文标题】`std::partition()` 的时间复杂度【英文标题】:Time complexity of `std::partition()` 【发布时间】:2016-02-03 03:30:45 【问题描述】:

根据cppreference:

复杂性 恰好std::distance(first,last) 谓词的应用程序和最多std::distance(first,last) 交换。如果 ForwardIt 最多满足 BidirectionalIterator 的要求 std::distance(first,last)/2 交换完成。

我查看了底部的示例实现:

template<class ForwardIt, class UnaryPredicate>
ForwardIt partition(ForwardIt first, ForwardIt last, UnaryPredicate p)

    if (first == last) return first;
    ForwardIt part(first++);
    if (first == last) return p(*part) ? first : part;
    while (first != last) 
        if (p(*part))
            ++part;
        else if (p(*first)) 
            iter_swap(part, first);
            ++part;
        
        ++first;
    
    return part;

我认为它最多执行 std::distance(first,last)/2 交换而不是 std::distance(first,last)。没有?

【问题讨论】:

对于 Alf 的答案示例,[0,1,1,1,1,1,…] 和谓词 _ != 0 请注意,这个实现是错误的,因为它调用谓词的次数太多了。 @T.C. ehhh,不是这样的。它恰好调用了 N 次 @AlexeyAndronov 不,循环的每次迭代都可以调用谓词两次。 @T.C.哦,你是对的 【参考方案1】:

这似乎是非双向迭代器的实现,仅用于向前。仅通过 n 个项目的序列前进,至少需要 n-1 次交换才能将单个非 p 项目从开始移动到结束。使用双向迭代器,可以从两端向内工作。

【讨论】:

双向迭代器的 libstdc++ 实现可以在例如stl_algo.h, line 1487 中找到(就在前向迭代器的下方)。

以上是关于`std::partition()` 的时间复杂度的主要内容,如果未能解决你的问题,请参考以下文章

并行化 std::nth_element 和 std::partition

实现 partition_unique 和 stable_partition_unique 算法

为forward_list实现stable_partition

为 forward_list 实现 stable_partition

stable_partition 并获得 O(nlogn) 交换

我应该在 openMP 并行区域内使用 gnu 并行模式函数吗(for-loop,tasks)