stable_partition如何成为自适应算法?

时间:2014-02-04 14:03:50

标签: c++ algorithm stl quicksort

stable_partition是c ++ STL的算法头文件中存在的函数模板。 我读到它是一种自适应算法,其时间复杂度为O(n * logn)或O(n),具体取决于某些因素。有人可以解释一下这些因素是什么以及时间复杂度如何取决于这些因素。谢谢!

3 个答案:

答案 0 :(得分:6)

2个实施

  1. “慢”O(n*logn)实施
  2. “更快”O(n)实施
  3. 快速实现需要使用大量内存,这可能无法使用。因此stable_partition询问操作系统是否有足够的可用内存,然后在两个实现之间进行选择。

    以下是 gcc 4.8.1实施中的一些示例,其中包含一些评论:

    template<typename _ForwardIterator, typename _Predicate>
        _ForwardIterator
        stable_partition(_ForwardIterator __first, _ForwardIterator __last,
                 _Predicate __pred)
        {
           ...
           ...
    
           /// Try to allocate enough memory for the faster algorithm
          _Temporary_buffer<_ForwardIterator, _ValueType> __buf(__first, __last);
    
        if (__buf.size() > 0)  /// If there is enough memory
          return
            std::__stable_partition_adaptive(__first, __last, __pred,
                          _DistanceType(__buf.requested_size()),
                          __buf.begin(),
                          _DistanceType(__buf.size()));
        else  /// If there is not enough memory
          return
            std::__inplace_stable_partition(__first, __pred,
                         _DistanceType(__buf.requested_size()));
        }
    

    此处std::__stable_partition_adaptive是快速算法,std::__inplace_stable_partition是慢速算法。

答案 1 :(得分:3)

这取决于可用的内存量。

如果你有足够的内存,一种方法就是简单地创建一个足够大的缓冲区,从正面和背面插入相应的元素,并在完成时将其放回原始元素中。这将花费O(n)时间。

如果没有足够的内存,this page提到了一个O(n log n)就地方法(也可能有另一种方法) - 如果你想重新安排-到前面和+到后面,你反复找到++++---形式的子阵列并将其(稳定地)重新排列到---++++(这可以用3个反转来完成 - 反转整个子阵列,然后负面部分,然后是正面部分。)

通过尝试分配内存并检查故障,可以简单地检查是否有足够的内存。一种方法是使用new,如果无法分配内存,可以抛出std::bad_alloc或返回空指针,具体取决于使用的版本。

答案 2 :(得分:2)

请参阅here

  

谓词的最后第一个应用程序,最多   (last-first)* log(last-first)如果没有足够的内存或交换,则交换   如果有足够的内存,则交换线性数。