How is stable_partition an adaptive algorithm?

后端 未结 3 893
一生所求
一生所求 2021-01-20 01:39

stable_partition is a function template present in algorithm header file of c++ STL. I read that it is an adaptive algorithm and its time complexity is O(n*logn) or O(n) dep

相关标签:
3条回答
  • 2021-01-20 02:28

    See here :

    Exactly last-first applications of the predicate and at most (last-first)*log(last-first) swaps if there is insufficient memory or linear number of swaps if sufficient memory is available.

    0 讨论(0)
  • 2021-01-20 02:35

    It depends on how much memory is available.

    If you have enough memory, one way is to simply create a big enough buffer, insert the respective elements from the front and back and put it back into the original when done. This will take O(n) time.

    If there isn't enough memory, this page mentions a O(n log n) in-place approach (there might be another approach as well) - if you want to rearrange - to the front and + to the back, you repeatedly find subarrays in the form ++++--- and rearrange it (stably) to ---++++ (which can be done with 3 reverses - reverse the whole subarray, then the negative part, then the positive part).

    The physical checking for enough memory can simply be done by trying to allocate the memory and checking for failure. One way to do this is with a new, which can either throw an std::bad_alloc or return a null pointer, depending on the version used, if it fails to allocate the memory.

    0 讨论(0)
  • 2021-01-20 02:39

    There are 2 implementations.

    1. "slower" O(n*logn) implementation
    2. "faster" O(n) implementation

    The fast implementation however needs to use a lot of memory, which may not be available. So the stable_partition asks the operating system if there is enough memory available and then chooses between the two implementations.

    Here is an example from the gcc 4.8.1 implementation with some of my comments:

    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()));
        }
    

    here std::__stable_partition_adaptive is the fast algorithm and std::__inplace_stable_partition is the slow algorithm.

    0 讨论(0)
提交回复
热议问题