STL相关算法部分源代码学习

STL部分源代码学习

// for_each.  Apply a function to every element of a range.
template <class _InputIter, class _Function>
_STLP_INLINE_LOOP _Function
for_each(_InputIter __first, _InputIter __last, _Function __f) {
  for ( ; __first != __last; ++__first)
    __f(*__first);
  return __f;
}

// count_if
template <class _InputIter, class _Predicate>
_STLP_INLINE_LOOP _STLP_DIFFERENCE_TYPE(_InputIter)
count_if(_InputIter __first, _InputIter __last, _Predicate __pred) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  _STLP_DIFFERENCE_TYPE(_InputIter) __n = 0;
  for ( ; __first != __last; ++__first) {
    if (__pred(*__first))
      ++__n;
  }
  return __n;
}

// adjacent_find.
// 找到第一组满足条件的相邻函数
template <class _ForwardIter, class _BinaryPredicate>
_STLP_INLINE_LOOP _ForwardIter
adjacent_find(_ForwardIter __first, _ForwardIter __last,
              _BinaryPredicate __binary_pred) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  if (__first == __last)
    return __last;
  _ForwardIter __next = __first;
  while(++__next != __last) {
    if (__binary_pred(*__first, *__next))
      return __first;
    __first = __next;
  }
  return __last;
}
// 找到相邻元素相等的第一组
template <class _ForwardIter>
_STLP_INLINE_LOOP _ForwardIter
adjacent_find(_ForwardIter __first, _ForwardIter __last) {
//调用一般的adjacent_find函数,加一个判断相等的仿函数__equal_to
  return adjacent_find(__first, __last,
                       _STLP_PRIV __equal_to(_STLP_VALUE_TYPE(__first, _ForwardIter)));
}

#if !defined (_STLP_NO_ANACHRONISMS)
template <class _InputIter, class _Tp, class _Size>
_STLP_INLINE_LOOP void
count(_InputIter __first, _InputIter __last, const _Tp& __val, _Size& __n) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
    for ( ; __first != __last; ++__first)
      if (*__first == __val)
        ++__n;
}

template <class _InputIter, class _Predicate, class _Size>
_STLP_INLINE_LOOP void
count_if(_InputIter __first, _InputIter __last, _Predicate __pred, _Size& __n) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  for ( ; __first != __last; ++__first)
    if (__pred(*__first))
      ++__n;
}
#endif

template <class _ForwardIter1, class _ForwardIter2>
_ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1,
                     _ForwardIter2 __first2, _ForwardIter2 __last2);

// search_n.  Search for __count consecutive copies of __val.
template <class _ForwardIter, class _Integer, class _Tp>
_ForwardIter search_n(_ForwardIter __first, _ForwardIter __last,
                      _Integer __count, const _Tp& __val);
template <class _ForwardIter, class _Integer, class _Tp, class _BinaryPred>
_ForwardIter search_n(_ForwardIter __first, _ForwardIter __last,
                      _Integer __count, const _Tp& __val, _BinaryPred __binary_pred);

template <class _InputIter, class _ForwardIter>
inline _InputIter find_first_of(_InputIter __first1, _InputIter __last1,
                                _ForwardIter __first2, _ForwardIter __last2) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1))
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first2, __last2))
  return _STLP_PRIV __find_first_of(__first1, __last1, __first2, __last2);
}

template <class _InputIter, class _ForwardIter, class _BinaryPredicate>
inline _InputIter
find_first_of(_InputIter __first1, _InputIter __last1,
              _ForwardIter __first2, _ForwardIter __last2, _BinaryPredicate __comp) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1))
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first2, __last2))
  return _STLP_PRIV __find_first_of(__first1, __last1, __first2, __last2, __comp);
}

template <class _ForwardIter1, class _ForwardIter2>
_ForwardIter1
find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
         _ForwardIter2 __first2, _ForwardIter2 __last2);

// swap_ranges
template <class _ForwardIter1, class _ForwardIter2>
_STLP_INLINE_LOOP _ForwardIter2
swap_ranges(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1))
  for ( ; __first1 != __last1; ++__first1, ++__first2)
    iter_swap(__first1, __first2);
  return __first2;
}

// transform
// 两个版本,第一个是针对一个range,每个元素经过仿函数处理之后的返回值赋给相应的元素。第二版本 :对两个range,经过二元仿函数处理结果赋值给新的range,返回新range的尾端。
template <class _InputIter, class _OutputIter, class _UnaryOperation>
_STLP_INLINE_LOOP _OutputIter
transform(_InputIter __first, _InputIter __last, _OutputIter __result, _UnaryOperation __opr) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  for ( ; __first != __last; ++__first, ++__result)
    *__result = __opr(*__first);
  return __result;
}
template <class _InputIter1, class _InputIter2, class _OutputIter, class _BinaryOperation>
_STLP_INLINE_LOOP _OutputIter
transform(_InputIter1 __first1, _InputIter1 __last1,
          _InputIter2 __first2, _OutputIter __result,_BinaryOperation __binary_op) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1))
  for ( ; __first1 != __last1; ++__first1, ++__first2, ++__result)
    *__result = __binary_op(*__first1, *__first2);
  return __result;
}

// replace_if, replace_copy, replace_copy_if
//区别在于针对更一般化的pred条件
template <class _ForwardIter, class _Predicate, class _Tp>
_STLP_INLINE_LOOP void
replace_if(_ForwardIter __first, _ForwardIter __last, _Predicate __pred, const _Tp& __new_value) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  for ( ; __first != __last; ++__first)
    if (__pred(*__first))
      *__first = __new_value;
}

template <class _InputIter, class _OutputIter, class _Tp>
_STLP_INLINE_LOOP  _OutputIter
replace_copy(_InputIter __first, _InputIter __last,_OutputIter __result,
             const _Tp& __old_value, const _Tp& __new_value) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  for ( ; __first != __last; ++__first, ++__result)
    *__result = *__first == __old_value ? __new_value : *__first;
  return __result;
}

template <class _Iterator, class _OutputIter, class _Predicate, class _Tp>
_STLP_INLINE_LOOP _OutputIter
replace_copy_if(_Iterator __first, _Iterator __last,
                _OutputIter __result,
                _Predicate __pred, const _Tp& __new_value) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  for ( ; __first != __last; ++__first, ++__result)
    *__result = __pred(*__first) ? __new_value : *__first;
  return __result;
}

// generate and generate_n
//generate 会调用__gen(一个不需要任何引数的function object), 将结果赋给[first, last)中的每一个元素
template <class _ForwardIter, class _Generator>
_STLP_INLINE_LOOP void
generate(_ForwardIter __first, _ForwardIter __last, _Generator __gen) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  for ( ; __first != __last; ++__first)
    *__first = __gen();
}

//generate_n会将gen所得结果赋给[first, first+n)中每个元素
template <class _OutputIter, class _Size, class _Generator>
_STLP_INLINE_LOOP void
generate_n(_OutputIter __first, _Size __n, _Generator __gen) {
  for ( ; __n > 0; --__n, ++__first)
    *__first = __gen();
}

// remove, remove_if, remove_copy, remove_copy_if
//这些函数动作都是稳定的。[first, new_last)中的各元素与[first, last)中的元素相对位置相同。 返回值都是执行结果range的尾端
//remove_copy移除[first, last) 区间中所有与value相等的元素(原容器没有任何改变),而是将结果复制到一个result标示的容器中
template <class _InputIter, class _OutputIter, class _Tp>
_STLP_INLINE_LOOP _OutputIter
remove_copy(_InputIter __first, _InputIter __last,_OutputIter __result, const _Tp& __val) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  for ( ; __first != __last; ++__first) {
    if (!(*__first == __val)) {
      *__result = *__first;
      ++__result;
    }
  }
  return __result;
}

//移除所有被仿函数pred评估为true的元素。将结果复制到新容器中
template <class _InputIter, class _OutputIter, class _Predicate>
_STLP_INLINE_LOOP _OutputIter
remove_copy_if(_InputIter __first, _InputIter __last, _OutputIter __result, _Predicate __pred) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  for ( ; __first != __last; ++__first) {
    if (!__pred(*__first)) {
      *__result = *__first;
      ++__result;
    }
  }
  return __result;
}

//remove会将数值value从[first, last)中移除。但是不会改变first 与 last 之间的距离。也就是value在[first, new_last)区间内被移除出去。remove是稳定的,区间左端的元素相对位置不变。[new_last, last)中的iterator仍可提领,但其指向之值我们不关心。可以使用成员函数erase将元素拿掉。
template <class _ForwardIter, class _Tp>
_STLP_INLINE_LOOP _ForwardIter
remove(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  __first = find(__first, __last, __val);

//等价: _ForwardIter __next = __first; 
//       return __first == __last ? __first : remove_copy(++__next, __last, __first, __val);
  if (__first == __last)
    return __first;
  else {
    _ForwardIter __next = __first;
//保持remove的特点,不会改变原有容器的大小。会调用remove_copy把结果复制到原容器中。
    return remove_copy(++__next, __last, __first, __val);
  }
}
//利用仿函数来实现
template <class _ForwardIter, class _Predicate>
_STLP_INLINE_LOOP _ForwardIter
remove_if(_ForwardIter __first, _ForwardIter __last, _Predicate __pred) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  __first = find_if(__first, __last, __pred);
  if ( __first == __last )
    return __first;
  else {
    _ForwardIter __next = __first;
    return remove_copy_if(++__next, __last, __first, __pred);
  }
}

// unique and unique_copy
// unique能够移除重复的元素,每当出现连续重复的元素时,unique便会删除除了第一个元素的所有元素。unique只是移除相邻重复的元素(从实现可以看出来,adjacent_find找出第一个相邻重复的元素。如果要移除所有相同的元素,那么需要结合sort函数,确定所有重复元素相邻。
template <class _InputIter, class _OutputIter>
_OutputIter unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result);

template <class _InputIter, class _OutputIter, class _BinaryPredicate>
_OutputIter unique_copy(_InputIter __first, _InputIter __last,_OutputIter __result,
                        _BinaryPredicate __binary_pred);

template <class _ForwardIter>
inline _ForwardIter unique(_ForwardIter __first, _ForwardIter __last) {
//            找出第一组相邻重复的元素。
  __first = adjacent_find(__first, __last);
  return unique_copy(__first, __last, __first);
}

template <class _ForwardIter, class _BinaryPredicate>
inline _ForwardIter unique(_ForwardIter __first, _ForwardIter __last,
                           _BinaryPredicate __binary_pred) {
  __first = adjacent_find(__first, __last, __binary_pred);
  return unique_copy(__first, __last, __first, __binary_pred);
}

// reverse and reverse_copy, and their auxiliary functions

_STLP_MOVE_TO_PRIV_NAMESPACE
// 迭代器的双向或随机定位能力影响算法的效率。所以该算法采用双层架构
template <class _BidirectionalIter>
_STLP_INLINE_LOOP void
__reverse(_BidirectionalIter __first, _BidirectionalIter __last, const bidirectional_iterator_tag &) {
// bidirectional_iterator_tag不能进行比较运算。
  for (; __first != __last && __first != --__last; ++__first)
    _STLP_STD::iter_swap(__first,__last);
}

template <class _RandomAccessIter>
_STLP_INLINE_LOOP void
__reverse(_RandomAccessIter __first, _RandomAccessIter __last, const random_access_iterator_tag &) {
// random_access_iterator_tag能做__first < __last 判断
  for (; __first < __last; ++__first)
    _STLP_STD::iter_swap(__first, --__last);
}

_STLP_MOVE_TO_STD_NAMESPACE

template <class _BidirectionalIter>
inline void
reverse(_BidirectionalIter __first, _BidirectionalIter __last) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  _STLP_PRIV __reverse(__first, __last, _STLP_ITERATOR_CATEGORY(__first, _BidirectionalIter));
}

template <class _BidirectionalIter, class _OutputIter>
_STLP_INLINE_LOOP
_OutputIter reverse_copy(_BidirectionalIter __first,
                         _BidirectionalIter __last,
                         _OutputIter __result) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  while (__first != __last) {
    --__last;
    *__result = *__last;
    ++__result;
  }
  return __result;
}

// 可以交换两个长度不同的区间, swap_ranges()只能交换两长度相同的区间。
template <class _ForwardIter>
void rotate(_ForwardIter __first, _ForwardIter __middle, _ForwardIter __last);

template <class _ForwardIter, class _OutputIter>
inline _OutputIter rotate_copy(_ForwardIter __first, _ForwardIter __middle,
                               _ForwardIter __last, _OutputIter __result) {
  return _STLP_STD::copy(__first, __middle, copy(__middle, __last, __result));
}

_STLP_MOVE_TO_STD_NAMESPACE
// 算法random_shuffle随即重排[first, last)的顺序,有N!种排序顺序(N = last - first)。这个算法有两个版本,版本一使用内部乱数产生器,版本二使用RandomNumberGenerator,具有局部性,每次调用都会改变
template <class _RandomAccessIter>
void random_shuffle(_RandomAccessIter __first,
                    _RandomAccessIter __last) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  if (__first == __last) return;
  for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
// 调用iter_swap(last-first)-1次
    iter_swap(__i, __first + _STLP_PRIV __random_number((__i - __first) + 1));
}

template <class _RandomAccessIter, class _RandomNumberGenerator>
void random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last,
                    _RandomNumberGenerator &__rand) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  if (__first == __last) return;
  for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
// 调用iter_swap(last-first)-1次
    iter_swap(__i, __first + __rand((__i - __first) + 1));
}

#if !defined (_STLP_NO_EXTENSIONS)
// random_sample and random_sample_n (extensions, not part of the standard).
template <class _ForwardIter, class _OutputIter, class _Distance>
_OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last,
                            _OutputIter __out_ite, const _Distance __n) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  _Distance __remaining = _STLP_STD::distance(__first, __last);
  _Distance __m = (min) (__n, __remaining);

  while (__m > 0) {
    if (_STLP_PRIV __random_number(__remaining) < __m) {
      *__out_ite = *__first;
      ++__out_ite;
      --__m;
    }

    --__remaining;
    ++__first;
  }
  return __out_ite;
}


template <class _ForwardIter, class _OutputIter, class _Distance,
          class _RandomNumberGenerator>
_OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last,
                            _OutputIter __out_ite, const _Distance __n,
                            _RandomNumberGenerator& __rand) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  _Distance __remaining = _STLP_STD::distance(__first, __last);
  _Distance __m = (min) (__n, __remaining);

  while (__m > 0) {
    if (__rand(__remaining) < __m) {
      *__out_ite = *__first;
      ++__out_ite;
      --__m;
    }

    --__remaining;
    ++__first;
  }
  return __out_ite;
}

_STLP_MOVE_TO_PRIV_NAMESPACE
// 算法random_sample 会随机的将[first, last)内的n个取样结果复制到__out_ite中
template <class _InputIter, class _RandomAccessIter, class _Distance>
_RandomAccessIter __random_sample(_InputIter __first, _InputIter __last,
                                  _RandomAccessIter __out_ite,
                                  const _Distance __n) {
  _Distance __m = 0;
  _Distance __t = __n;
// 将原容器中__m个元素复制到新容器中。 __m的结果应是min(__n, __last-__first)
  for ( ; __first != __last && __m < __n; ++__m, ++__first)
    __out_ite[__m] = *__first;
// 这样做保证了每个元素被选中的概率为n/N (n为新容器的大小,此处即__m, N为(__last-__first)
  while (__first != __last) {
    ++__t;
    _Distance __M = __random_number(__t);
    if (__M < __n)
      __out_ite[__M] = *__first;
    ++__first;
  }

  return __out_ite + __m;
}

template <class _InputIter, class _RandomAccessIter,
          class _RandomNumberGenerator, class _Distance>
_RandomAccessIter __random_sample(_InputIter __first, _InputIter __last,
                                  _RandomAccessIter __out_ite,
                                  _RandomNumberGenerator& __rand,
                                  const _Distance __n) {
  _Distance __m = 0;
  _Distance __t = __n;
  for ( ; __first != __last && __m < __n; ++__m, ++__first)
    __out_ite[__m] = *__first;

  while (__first != __last) {
    ++__t;
    _Distance __M = __rand(__t);
    if (__M < __n)
      __out_ite[__M] = *__first;
    ++__first;
  }

  return __out_ite + __m;
}

_STLP_MOVE_TO_STD_NAMESPACE
// random_sample 转发函数,会随机的将[first, last)内的n个取样结果复制到__out_ite中
template <class _InputIter, class _RandomAccessIter>
_RandomAccessIter
random_sample(_InputIter __first, _InputIter __last,
              _RandomAccessIter __out_first, _RandomAccessIter __out_last) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__out_first, __out_last))
  return _STLP_PRIV __random_sample(__first, __last,
                                    __out_first, __out_last - __out_first);
}

template <class _InputIter, class _RandomAccessIter, class _RandomNumberGenerator>
_RandomAccessIter
random_sample(_InputIter __first, _InputIter __last,
              _RandomAccessIter __out_first, _RandomAccessIter __out_last,
              _RandomNumberGenerator& __rand) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__out_first, __out_last))
  return _STLP_PRIV __random_sample(__first, __last,
                                    __out_first, __rand,
                                    __out_last - __out_first);
}

#endif /* _STLP_NO_EXTENSIONS */
// partition, stable_partition, and their auxiliary functions
_STLP_MOVE_TO_PRIV_NAMESPACE
// forward_iterator_tag迭代器类型的内部处理,只能单向处理
template <class _ForwardIter, class _Predicate>
_STLP_INLINE_LOOP _ForwardIter __partition(_ForwardIter __first,
                                           _ForwardIter __last,
                                           _Predicate   __pred,
                                           const forward_iterator_tag &) {
  if (__first == __last) return __first;
// 检查满足条件的元素,如果知道容器尾端全部满足则无需交换,直接返回尾端迭代器
  while (__pred(*__first))
    if (++__first == __last) return __first;

  _ForwardIter __next = __first;
// 通过使用两个迭代器,把满足条件的元素全部往前插
  while (++__next != __last) {
    if (__pred(*__next)) {
      _STLP_STD::swap(*__first, *__next);
      ++__first;
    }
  }
  return __first;
}

//  bidirectional_iterator_tag迭代器内部实际处理函数,可以双向进行
template <class _BidirectionalIter, class _Predicate>
_STLP_INLINE_LOOP _BidirectionalIter __partition(_BidirectionalIter __first,
                                                 _BidirectionalIter __last,
                                                 _Predicate __pred,
                                                 const bidirectional_iterator_tag &) {
  for (;;) {
//  循环正向找到第一个不满足的iterator 
    for (;;) {
      if (__first == __last)
        return __first;
      else if (__pred(*__first))
        ++__first;
      else
        break;
    }
    --__last;
//   同样反向找到满足条件的Iterator
    for (;;) {
      if (__first == __last)
        return __first;
      else if (!__pred(*__last))
        --__last;
      else
        break;
    }
//  交换找到的两个迭代器所指元素
    iter_swap(__first, __last);
//  完成后first++继续外层循环,知道遍历整个容器
    ++__first;
  }
}

#if defined (_STLP_NONTEMPL_BASE_MATCH_BUG)
template <class _BidirectionalIter, class _Predicate>
inline
_BidirectionalIter __partition(_BidirectionalIter __first,
                               _BidirectionalIter __last,
                               _Predicate __pred,
                               const random_access_iterator_tag &) {
  return __partition(__first, __last, __pred, bidirectional_iterator_tag());
}
#endif
// 和前面的一样,不同的迭代器行为会影响算法的效率。所以两层架构- 分派函数
// partition 导致[first, last)内会存在某个iterator middle, 使得[first, middle) 内的每个iterator i 都导致__pre(*i)为true,并使得[middle, last) 内的每个iterator i都导致pred(*i)为false。partition 不必保存元素原来的相对位置
_STLP_MOVE_TO_STD_NAMESPACE

template <class _ForwardIter, class _Predicate>
_ForwardIter partition(_ForwardIter __first, _ForwardIter __last, _Predicate   __pred) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  return _STLP_PRIV __partition(__first, __last, __pred, _STLP_ITERATOR_CATEGORY(__first, _ForwardIter));
}


/* __pred_of_first: false if we know that __pred(*__first) is false,
 *                  true when we don't know the result of __pred(*__first).
 * __not_pred_of_before_last: true if we know that __pred(*--__last) is true,
 *                            false when we don't know the result of __pred(*--__last).
 */
_STLP_MOVE_TO_PRIV_NAMESPACE

// 缓冲区请求失败,会调用此函数进行处理
template <class _ForwardIter, class _Predicate, class _Distance>
_ForwardIter __inplace_stable_partition(_ForwardIter __first,
                                        _ForwardIter __last,
                                        _Predicate __pred, _Distance __len,
                                        bool __pred_of_first, bool __pred_of_before_last) {
  if (__len == 1)
    return (__pred_of_first && (__pred_of_before_last || __pred(*__first))) ? __last : __first;
  _ForwardIter __middle = __first;
  _Distance __half_len = __len / 2;
  _STLP_STD::advance(__middle, __half_len);
  return _STLP_PRIV __rotate(_STLP_PRIV __inplace_stable_partition(__first, __middle, __pred, __half_len, __pred_of_first, false),
                             __middle,
                             _STLP_PRIV __inplace_stable_partition(__middle, __last, __pred, __len - __half_len, true, __pred_of_before_last));
}

template <class _ForwardIter, class _Pointer, class _Predicate,
          class _Distance>
_ForwardIter __stable_partition_adaptive(_ForwardIter __first,
                                         _ForwardIter __last,
                                         _Predicate __pred, _Distance __len,
                                         _Pointer __buffer, _Distance __buffer_size,
                                         bool __pred_of_first, bool __pred_of_before_last) {
  if (__len <= __buffer_size) {
    _ForwardIter __result1 = __first;
    _Pointer __result2 = __buffer;
    if ((__first != __last) && (!__pred_of_first || __pred(*__first))) {
      *__result2 = *__first;
      ++__result2; ++__first; --__len;
    }
    for (; __first != __last ; ++__first, --__len) {
      if (((__len == 1) && (__pred_of_before_last || __pred(*__first))) ||
          ((__len != 1) && __pred(*__first))){
        *__result1 = *__first;
        ++__result1;
      }
      else {
        *__result2 = *__first;
        ++__result2;
      }
    }
    _STLP_STD::copy(__buffer, __result2, __result1);
    return __result1;
  }
  else {
    _ForwardIter __middle = __first;
    _Distance __half_len = __len / 2;
    _STLP_STD::advance(__middle, __half_len);
    return _STLP_PRIV __rotate(_STLP_PRIV __stable_partition_adaptive(__first, __middle, __pred,
                                                                      __half_len, __buffer, __buffer_size,
                                                                      __pred_of_first, false),
                               __middle,
                               _STLP_PRIV __stable_partition_adaptive(__middle, __last, __pred,
                                                                      __len - __half_len, __buffer, __buffer_size,
                                                                      true, __pred_of_before_last));
  }
}

template <class _ForwardIter, class _Predicate, class _Tp, class _Distance>
inline _ForwardIter
__stable_partition_aux_aux(_ForwardIter __first, _ForwardIter __last,
                           _Predicate __pred, _Tp*, _Distance*, bool __pred_of_before_last) {
// 请求分配临时缓冲区
  _Temporary_buffer<_ForwardIter, _Tp> __buf(__first, __last);
  _STLP_MPWFIX_TRY    //*TY 06/01/2000 - they forget to call dtor for _Temporary_buffer if no try/catch block is present
  return (__buf.size() > 0) ?
    __stable_partition_adaptive(__first, __last, __pred,
                                _Distance(__buf.requested_size()),
                                __buf.begin(), __buf.size(),
                                false, __pred_of_before_last)  :
    __inplace_stable_partition(__first, __last, __pred,
                               _Distance(__buf.requested_size()),
                               false, __pred_of_before_last);
  _STLP_MPWFIX_CATCH  //*TY 06/01/2000 - they forget to call dtor for _Temporary_buffer if no try/catch block is present
}

template <class _ForwardIter, class _Predicate>
_ForwardIter
__stable_partition_aux(_ForwardIter __first, _ForwardIter __last, _Predicate __pred,
                       const forward_iterator_tag &) {
  return __stable_partition_aux_aux(__first, __last, __pred,
                                    _STLP_VALUE_TYPE(__first, _ForwardIter),
                                    _STLP_DISTANCE_TYPE(__first, _ForwardIter), false);
}

template <class _BidirectIter, class _Predicate>
_BidirectIter
__stable_partition_aux(_BidirectIter __first, _BidirectIter __last, _Predicate __pred,
                       const bidirectional_iterator_tag &) {
// 反向找到第一个满足pred的元素
  for (--__last;;) {
    if (__first == __last)
      return __first;
    else if (!__pred(*__last))
      --__last;
    else
      break;
  }
  ++__last;
  //Here we know that __pred(*--__last) is true
  return __stable_partition_aux_aux(__first, __last, __pred,
                                    _STLP_VALUE_TYPE(__first, _BidirectIter),
                                    _STLP_DISTANCE_TYPE(__first, _BidirectIter), true);
}

#if defined (_STLP_NONTEMPL_BASE_MATCH_BUG)
template <class _BidirectIter, class _Predicate>
_BidirectIter
__stable_partition_aux(_BidirectIter __first, _BidirectIter __last, _Predicate __pred,
                       const random_access_iterator_tag &) {
  return __stable_partition_aux(__first, __last, __pred, bidirectional_iterator_tag());
}
#endif

_STLP_MOVE_TO_STD_NAMESPACE
// stable_partition 和partition 区别在于,它保持了元素相对位置不变。partition执行速度快。stable_partition是一个adaptive算法:会试图分配临时内存缓冲区,运行期复杂度取决于缓冲区中有多少内存
template <class _ForwardIter, class _Predicate>
_ForwardIter
stable_partition(_ForwardIter __first, _ForwardIter __last, _Predicate __pred) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  for (;;) {
    if (__first == __last)
      return __first;
// 先找到第一个不满足的元素
    else if (__pred(*__first))
      ++__first;
    else
      break;
  }
// 根据迭代器的类型进行转发,调用相应的处理函数
  return _STLP_PRIV __stable_partition_aux(__first, __last, __pred,
                                           _STLP_ITERATOR_CATEGORY(__first, _ForwardIter));
}
// sort() and its auxiliary functions.
_STLP_MOVE_TO_PRIV_NAMESPACE

template <class _Size>
inline _Size __lg(_Size __n) {
  _Size __k;
  for (__k = 0; __n != 1; __n >>= 1) ++__k;
  return __k;
}
_STLP_MOVE_TO_PRIV_NAMESPACE
// 分割函数,选取一个__pivot(枢轴),
template <class _RandomAccessIter, class _Tp, class _Compare>
_RandomAccessIter __unguarded_partition(_RandomAccessIter __first,
                                        _RandomAccessIter __last,
                                        _Tp __pivot, _Compare __comp) {
  for (;;) {
    while (__comp(*__first, __pivot)) { // 假设__comp为less<int>, first 找到 >= pivot的元素停下来,
      _STLP_VERBOSE_ASSERT(!__comp(__pivot, *__first), _StlMsg_INVALID_STRICT_WEAK_PREDICATE)
      ++__first;
    }
    --__last;
    while (__comp(__pivot, *__last)) {  // last 找到 <= pivot的元素就停
      _STLP_VERBOSE_ASSERT(!__comp(*__last, __pivot), _StlMsg_INVALID_STRICT_WEAK_PREDICATE)
      --__last;
    }
    if (!(__first < __last)) // 判断交错, 交错就结束
      return __first;
    iter_swap(__first, __last);  //大小值换位
    ++__first;
  }
}

// SGI STL sort()两个版本,根据排序的参考函数分类。值得注意的是sort()只适用于RandomAccessIterator 
// 
// sort() and its auxiliary functions.
#define __stl_threshold  16

template <class _RandomAccessIter, class _Tp, class _Compare>
void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val,
                               _Compare __comp) {
//  内循环
  _RandomAccessIter __next = __last;
  --__next;
  while (__comp(__val, *__next)) { // 逆转对存在
    _STLP_VERBOSE_ASSERT(!__comp(*__next, __val), _StlMsg_INVALID_STRICT_WEAK_PREDICATE)
    *__last = *__next;  // 调整
    __last = __next;     //调整迭代器
    --__next;            // 左移一个位置
  }
  *__last = __val;       //value最终位置
}


template <class _RandomAccessIter, class _Tp, class _Compare>
inline void __linear_insert(_RandomAccessIter __first,
                            _RandomAccessIter __last, _Tp __val, _Compare __comp) {
  //*TY 12/26/1998 - added __val as a paramter
  //  _Tp __val = *__last;        //*TY 12/26/1998 - __val supplied by caller

  if (__comp(__val, *__first)) {
    _STLP_VERBOSE_ASSERT(!__comp(*__first, __val), _StlMsg_INVALID_STRICT_WEAK_PREDICATE)
 // 将整个区间向右移一个位置
    copy_backward(__first, __last, __last + 1);
    *__first = __val;
  }
  else
    __unguarded_linear_insert(__last, __val, __comp);
}

template <class _RandomAccessIter, class _Tp, class _Compare>
void __insertion_sort(_RandomAccessIter __first,
                      _RandomAccessIter __last,
                      _Tp *, _Compare __comp) {
  if (__first == __last) return;
    // 外循环, [first, i)形成子区间
  for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
    __linear_insert<_RandomAccessIter, _Tp, _Compare>(__first, __i, *__i, __comp);  //*TY 12/26/1998 - supply *__i as __val
}

template <class _RandomAccessIter, class _Tp, class _Compare>
void __unguarded_insertion_sort_aux(_RandomAccessIter __first,
                                    _RandomAccessIter __last,
                                    _Tp*, _Compare __comp) {
  for (_RandomAccessIter __i = __first; __i != __last; ++__i)
    __unguarded_linear_insert<_RandomAccessIter, _Tp, _Compare>(__i, *__i, __comp);
}

template <class _RandomAccessIter, class _Compare>
inline void __unguarded_insertion_sort(_RandomAccessIter __first,
                                       _RandomAccessIter __last,
                                       _Compare __comp) {
  __unguarded_insertion_sort_aux(__first, __last, _STLP_VALUE_TYPE(__first, _RandomAccessIter), __comp);
}

template <class _RandomAccessIter, class _Compare>
void __final_insertion_sort(_RandomAccessIter __first,
                            _RandomAccessIter __last, _Compare __comp) {
    // 判断元素个数是否大于16, 如果否, 则调用插入排序__insertion_sort,如果是,将[first, last)分割成长度为16一段子序列,和另一段子序列,在针对两个子序列跟别调用插入排序__insertion_sort和__unguarded_insertion_sort
  if (__last - __first > __stl_threshold) {
    __insertion_sort(__first, __first + __stl_threshold, _STLP_VALUE_TYPE(__first,_RandomAccessIter), __comp);
    __unguarded_insertion_sort(__first + __stl_threshold, __last, __comp);
  }
  else
    __insertion_sort(__first, __last, _STLP_VALUE_TYPE(__first,_RandomAccessIter), __comp);
}
// sort()函数大部分情况下和quicksort排序相同, 但是当分割行为有恶化为二次行为的倾向时,能够自我侦测,转而改用heap sort。
template <class _RandomAccessIter, class _Tp, class _Size, class _Compare>
void __introsort_loop(_RandomAccessIter __first,
                      _RandomAccessIter __last, _Tp*,
                      _Size __depth_limit, _Compare __comp) {//__depth_limit为分割的深度
  while (__last - __first > __stl_threshold) {  //__stl_threshold全局常数,16
    if (__depth_limit == 0) {                   //至此分割恶化
      partial_sort(__first, __last, __last, __comp);  // 改用heapsort
      return;
    }
    --__depth_limit;
    //以下median-of-3 partition,选择一个够好的枢轴并决定分割点,分割点降落在cut上
    _RandomAccessIter __cut =
      __unguarded_partition(__first, __last,
                            _Tp(__median(*__first,
                                         *(__first + (__last - __first)/2),
                                         *(__last - 1), __comp)),
       __comp);
    //对右半段递归进行sort
    __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit, __comp);
    __last = __cut; // 现在回到while循环,准备对左半段递归进行sort
  }
}

_STLP_MOVE_TO_STD_NAMESPACE

template <class _RandomAccessIter>
void sort(_RandomAccessIter __first, _RandomAccessIter __last) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  if (__first != __last) {
    _STLP_PRIV __introsort_loop(__first, __last,
                                _STLP_VALUE_TYPE(__first, _RandomAccessIter),
                                _STLP_PRIV __lg(__last - __first) * 2,
                                _STLP_PRIV __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter)));
    _STLP_PRIV __final_insertion_sort(__first, __last,
                                      _STLP_PRIV __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter)));
  }
}


template <class _RandomAccessIter, class _Compare>
void sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  if (__first != __last) {
    _STLP_PRIV __introsort_loop(__first, __last,
                                _STLP_VALUE_TYPE(__first, _RandomAccessIter),
                                _STLP_PRIV __lg(__last - __first) * 2, __comp); // __lg()用来控制分割恶化的情况,当元素的个数为40时, 倒数第二参数为10, 即允许最多分割10层。
// 当 __introsort_loop结束后,[first, last)中有多个"元素个数小于16"的子序列,每个子序列都有相当程度的排序,但未完全排序
    _STLP_PRIV __final_insertion_sort(__first, __last, __comp);
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值