STL相关算法部分源代码学习
来源:互联网 发布:php json 储存数据 编辑:程序博客网 时间:2024/06/05 17:24
STL部分源代码学习
// for_each. Apply a function to every element of a range.template <class _InputIter, class _Function>_STLP_INLINE_LOOP _Functionfor_each(_InputIter __first, _InputIter __last, _Function __f) { for ( ; __first != __last; ++__first) __f(*__first); return __f;}// count_iftemplate <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 _ForwardIteradjacent_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 _ForwardIteradjacent_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 voidcount(_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 voidcount_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;}#endiftemplate <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 _InputIterfind_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>_ForwardIter1find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, _ForwardIter2 __first2, _ForwardIter2 __last2);// swap_rangestemplate <class _ForwardIter1, class _ForwardIter2>_STLP_INLINE_LOOP _ForwardIter2swap_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 _OutputItertransform(_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 _OutputItertransform(_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 voidreplace_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 _OutputIterreplace_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 _OutputIterreplace_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 voidgenerate(_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 voidgenerate_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 _OutputIterremove_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 _OutputIterremove_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 _ForwardIterremove(_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 _ForwardIterremove_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_NAMESPACEtemplate <class _BidirectionalIter>inline voidreverse(_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>_RandomAccessIterrandom_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>_RandomAccessIterrandom_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_NAMESPACEtemplate <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>_ForwardIterstable_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_NAMESPACEtemplate <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 16template <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_NAMESPACEtemplate <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
- STL相关算法部分源代码学习
- STL迭代器与部分算法学习笔记
- stl中binary_search算法相关学习;
- STL部分算法
- STL之set相关算法
- stl中set相关算法
- 学习STL算法:adjacent_find
- 学习STL算法:count
- 学习STL算法:equal
- STL算法学习
- STL算法学习
- STL算法学习
- STL算法学习[转载]
- STL算法学习
- STL算法学习
- STL算法学习小结
- STL算法学习
- STL算法学习
- 在文件中加入数据的简单案例
- Technocup 2017 - Elimination Round 1 C 交互
- 基于Goolgle最新NavigationDrawer实现全屏水平平移
- 二叉树的操作3非递归算法求二叉树的高度
- mysql主从复制
- STL相关算法部分源代码学习
- 云帮社区版迎来10.25更新档
- 1020. 月饼 (25)
- 【XJOI】NOIP2016提高组冲剌题1 T1 挖金矿
- USB-to-serial 设备无法启动 代码(10)
- The list of sources could not be read.
- poj 1054 The Troublesome Frog 枚举+二分搜索
- 解决字符集乱码方法集合
- Android开发——布局性能优化的一些技巧(一)