STL源代码分析——STL算法sort排序算法

时间:2022-09-07 18:34:25

前言

因为在前文的《STL算法剖析》中,源代码剖析许多,不方便学习,也不方便以后复习。这里把这些算法进行归类,对他们单独的源代码剖析进行解说。本文介绍的STL算法中的sort排序算法,SGI
STL中的排序算法不是简单的高速排序,而是交叉利用各种排序:堆排序、插入排序和高速排序;这样做的目的是提高效率。针对数据量比較大的採用高速排序,数据量比較小的能够採用堆排序或插入排序。

本文介绍了有关排序的算法random_shuffle、partition、stable_partition、sort、stable_sort、partial_sort、partial_sort_copy、nth_element;注意:STL的sort排序算法的迭代器必须是随机訪问迭代器。

sort排序算法剖析

// Return a random number in the range [0, __n).  This function encapsulates
// whether we're using rand (part of the standard C library) or lrand48
// (not standard, but a much better choice whenever it's available). template <class _Distance>
inline _Distance __random_number(_Distance __n) {
#ifdef __STL_NO_DRAND48
return rand() % __n;
#else
return lrand48() % __n;
#endif
} // random_shuffle
//将区间[first,last)内的元素随机重排
//两个版本号的不同是随机数的取得
//版本号一是使用内部随机数产生器
//版本号二是使用一个会产生随机数的仿函数 /*
函数功能:Rearranges the elements in the range [first,last) randomly.
函数原型:
generator by default (1)
template <class RandomAccessIterator>
void random_shuffle (RandomAccessIterator first, RandomAccessIterator last);
specific generator (2)
template <class RandomAccessIterator, class RandomNumberGenerator>
void random_shuffle (RandomAccessIterator first, RandomAccessIterator last,
RandomNumberGenerator& gen);
*/
//版本号一
template <class _RandomAccessIter>
inline void random_shuffle(_RandomAccessIter __first,
_RandomAccessIter __last) {
__STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
if (__first == __last) return;
for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
iter_swap(__i, __first + __random_number((__i - __first) + 1));
}
//版本号二
template <class _RandomAccessIter, class _RandomNumberGenerator>
void random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last,
_RandomNumberGenerator& __rand) {
__STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
if (__first == __last) return;
for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
iter_swap(__i, __first + __rand((__i - __first) + 1));
} // 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, const _Distance __n)
{
__STL_REQUIRES(_ForwardIter, _ForwardIterator);
__STL_REQUIRES(_OutputIter, _OutputIterator);
_Distance __remaining = 0;
distance(__first, __last, __remaining);
_Distance __m = min(__n, __remaining); while (__m > 0) {
if (__random_number(__remaining) < __m) {
*__out = *__first;
++__out;
--__m;
} --__remaining;
++__first;
}
return __out;
} template <class _ForwardIter, class _OutputIter, class _Distance,
class _RandomNumberGenerator>
_OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last,
_OutputIter __out, const _Distance __n,
_RandomNumberGenerator& __rand)
{
__STL_REQUIRES(_ForwardIter, _ForwardIterator);
__STL_REQUIRES(_OutputIter, _OutputIterator);
__STL_UNARY_FUNCTION_CHECK(_RandomNumberGenerator, _Distance, _Distance);
_Distance __remaining = 0;
distance(__first, __last, __remaining);
_Distance __m = min(__n, __remaining); while (__m > 0) {
if (__rand(__remaining) < __m) {
*__out = *__first;
++__out;
--__m;
} --__remaining;
++__first;
}
return __out;
} template <class _InputIter, class _RandomAccessIter, class _Distance>
_RandomAccessIter __random_sample(_InputIter __first, _InputIter __last,
_RandomAccessIter __out,
const _Distance __n)
{
_Distance __m = 0;
_Distance __t = __n;
for ( ; __first != __last && __m < __n; ++__m, ++__first)
__out[__m] = *__first; while (__first != __last) {
++__t;
_Distance __M = __random_number(__t);
if (__M < __n)
__out[__M] = *__first;
++__first;
} return __out + __m;
} template <class _InputIter, class _RandomAccessIter,
class _RandomNumberGenerator, class _Distance>
_RandomAccessIter __random_sample(_InputIter __first, _InputIter __last,
_RandomAccessIter __out,
_RandomNumberGenerator& __rand,
const _Distance __n)
{
__STL_UNARY_FUNCTION_CHECK(_RandomNumberGenerator, _Distance, _Distance);
_Distance __m = 0;
_Distance __t = __n;
for ( ; __first != __last && __m < __n; ++__m, ++__first)
__out[__m] = *__first; while (__first != __last) {
++__t;
_Distance __M = __rand(__t);
if (__M < __n)
__out[__M] = *__first;
++__first;
} return __out + __m;
} template <class _InputIter, class _RandomAccessIter>
inline _RandomAccessIter
random_sample(_InputIter __first, _InputIter __last,
_RandomAccessIter __out_first, _RandomAccessIter __out_last)
{
__STL_REQUIRES(_InputIter, _InputIterator);
__STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
return __random_sample(__first, __last,
__out_first, __out_last - __out_first);
} template <class _InputIter, class _RandomAccessIter,
class _RandomNumberGenerator>
inline _RandomAccessIter
random_sample(_InputIter __first, _InputIter __last,
_RandomAccessIter __out_first, _RandomAccessIter __out_last,
_RandomNumberGenerator& __rand)
{
__STL_REQUIRES(_InputIter, _InputIterator);
__STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
return __random_sample(__first, __last,
__out_first, __rand,
__out_last - __out_first);
} // partition, stable_partition, and their auxiliary functions
//若迭代器的类型为forward_iterator_tag。则调用此函数
template <class _ForwardIter, class _Predicate>
_ForwardIter __partition(_ForwardIter __first,
_ForwardIter __last,
_Predicate __pred,
forward_iterator_tag) {
if (__first == __last) return __first;//若为空。直接退出 while (__pred(*__first))//若pred出first的值为true
if (++__first == __last) return __first;//先移动迭代器first,在推断是否到达尾端last _ForwardIter __next = __first;//继续推断 while (++__next != __last)//若下一个位置依旧不是尾端
if (__pred(*__next)) {//继续pred出next的值。若为true
swap(*__first, *__next);//交换值
++__first;//继续下一位置
} return __first;
}
//若迭代器的类型为bidirectional_iterator_tag。则调用此函数
template <class _BidirectionalIter, class _Predicate>
_BidirectionalIter __partition(_BidirectionalIter __first,
_BidirectionalIter __last,
_Predicate __pred,
bidirectional_iterator_tag) {
while (true) {
while (true)
if (__first == __last)//若为空
return __first;//直接退出
else if (__pred(*__first))//first的值符合不移动条件。则不移动该值
++__first;//仅仅移动迭代器
else//若头指针符合移动
break;//跳出循环
--__last;//尾指针回溯
while (true)
if (__first == __last)//头指针等于尾指针
return __first;//操作结束
else if (!__pred(*__last))//尾指针的元素符合不移动操作
--__last;//至移动迭代器,并不移动详细元素
else//尾指针的元素符合移动操作
break;//跳出循环
iter_swap(__first, __last);//头尾指针交换元素
++__first;//准备下一次循环
}
}
//将区间[first,last)的元素进行排序,被pred推断为true的放在区间的前段。判定为false的放在区间后段
//该算算可能会使元素的元素位置放生改变.
/*
算法功能:Rearranges the elements from the range [first,last), in such a way that all the elements
for which pred returns true precede all those for which it returns false.
The iterator returned points to the first element of the second group. 算法原型:
template <class BidirectionalIterator, class UnaryPredicate>
BidirectionalIterator partition (BidirectionalIterator first,
BidirectionalIterator last, UnaryPredicate pred);
*/
template <class _ForwardIter, class _Predicate>
inline _ForwardIter partition(_ForwardIter __first,
_ForwardIter __last,
_Predicate __pred) {
__STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator);
__STL_UNARY_FUNCTION_CHECK(_Predicate, bool,
typename iterator_traits<_ForwardIter>::value_type);
//首先萃取出迭代器first的类型,依据迭代器的类型调用不同的函数
return __partition(__first, __last, __pred, __ITERATOR_CATEGORY(__first));
}
//partition函数举例:
/*
#include <iostream> // std::cout
#include <algorithm> // std::partition
#include <vector> // std::vector bool IsOdd (int i) { return (i%2)==1; } int main () {
std::vector<int> myvector; // set some values:
for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9 std::vector<int>::iterator bound;
bound = std::partition (myvector.begin(), myvector.end(), IsOdd); // print out content:
std::cout << "odd elements:";
for (std::vector<int>::iterator it=myvector.begin(); it!=bound; ++it)
std::cout << ' ' << *it;
std::cout << '\n'; std::cout << "even elements:";
for (std::vector<int>::iterator it=bound; it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n'; return 0;
}
Output:
odd elements: 1 9 3 7 5
even elements: 6 4 8 2 */ template <class _ForwardIter, class _Predicate, class _Distance>
_ForwardIter __inplace_stable_partition(_ForwardIter __first,
_ForwardIter __last,
_Predicate __pred, _Distance __len) {
if (__len == 1)
return __pred(*__first) ? __last : __first;
_ForwardIter __middle = __first;
advance(__middle, __len / 2);
return rotate(__inplace_stable_partition(__first, __middle, __pred,
__len / 2),
__middle,
__inplace_stable_partition(__middle, __last, __pred,
__len - __len / 2));
} 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)
{
if (__len <= __buffer_size) {
_ForwardIter __result1 = __first;
_Pointer __result2 = __buffer;
for ( ; __first != __last ; ++__first)
if (__pred(*__first)) {
*__result1 = *__first;
++__result1;
}
else {
*__result2 = *__first;
++__result2;
}
copy(__buffer, __result2, __result1);
return __result1;
}
else {
_ForwardIter __middle = __first;
advance(__middle, __len / 2);
return rotate(__stable_partition_adaptive(
__first, __middle, __pred,
__len / 2, __buffer, __buffer_size),
__middle,
__stable_partition_adaptive(
__middle, __last, __pred,
__len - __len / 2, __buffer, __buffer_size));
}
} template <class _ForwardIter, class _Predicate, class _Tp, class _Distance>
inline _ForwardIter
__stable_partition_aux(_ForwardIter __first, _ForwardIter __last,
_Predicate __pred, _Tp*, _Distance*)
{
_Temporary_buffer<_ForwardIter, _Tp> __buf(__first, __last);
if (__buf.size() > 0)
return __stable_partition_adaptive(__first, __last, __pred,
_Distance(__buf.requested_size()),
__buf.begin(), __buf.size());
else
return __inplace_stable_partition(__first, __last, __pred,
_Distance(__buf.requested_size()));
} template <class _ForwardIter, class _Predicate>
inline _ForwardIter stable_partition(_ForwardIter __first,
_ForwardIter __last,
_Predicate __pred) {
__STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator);
__STL_UNARY_FUNCTION_CHECK(_Predicate, bool,
typename iterator_traits<_ForwardIter>::value_type);
if (__first == __last)
return __first;
else
return __stable_partition_aux(__first, __last, __pred,
__VALUE_TYPE(__first),
__DISTANCE_TYPE(__first));
}
//找出高速排序的枢纽位置
//版本号一採用operator<
template <class _RandomAccessIter, class _Tp>
_RandomAccessIter __unguarded_partition(_RandomAccessIter __first,
_RandomAccessIter __last,
_Tp __pivot)
{
//找出枢纽轴的位置
//令头端迭代器向尾端方向移动。尾端迭代器向头端移动。
//当*first不小于枢纽值时。就停下来。当*last不大于枢纽值时也停下来,然后检測两个迭代器是否交错
//假设first仍然在左側而last仍然在右側,就交换两个元素。然后各自调整位置,向*逼近,再继续运行同样的行为.
//直到first和last两个迭代器交错,此时表示已找到枢纽轴位置即first所在的位置
while (true) {
while (*__first < __pivot)
++__first;//first向尾端移动。直到遇到不小于枢纽值时,停止
--__last;
while (__pivot < *__last)
--__last;//last向头端移动,直到遇到不大于枢纽值时。停止
if (!(__first < __last))//检測两个迭代器是否交错
return __first;//交错,则此时已找到。即为first迭代器所指位置
iter_swap(__first, __last);//否则交换迭代器所指的元素
++__first;//继续运行同样行为
}
}
//版本号一採用__comp
template <class _RandomAccessIter, class _Tp, class _Compare>
_RandomAccessIter __unguarded_partition(_RandomAccessIter __first,
_RandomAccessIter __last,
_Tp __pivot, _Compare __comp)
{
while (true) {
while (__comp(*__first, __pivot))
++__first;
--__last;
while (__comp(__pivot, *__last))
--__last;
if (!(__first < __last))
return __first;
iter_swap(__first, __last);
++__first;
}
} const int __stl_threshold = 16; // sort() and its auxiliary functions.
//__insertion_sort版本号一的辅助函数
template <class _RandomAccessIter, class _Tp>
void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val) {
_RandomAccessIter __next = __last;
--__next;
//__insertion_sort的内循环
//注意:一旦不再出现逆转对。循环就结束
while (__val < *__next) {//存在逆转对
*__last = *__next;//调整元素
__last = __next;//调整迭代器
--__next;//左移一个位置
}
*__last = __val;//value的正确插入位置
}
//__insertion_sort版本号二的辅助函数
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)) {
*__last = *__next;
__last = __next;
--__next;
}
*__last = __val;
}
//__insertion_sort版本号一的辅助函数
template <class _RandomAccessIter, class _Tp>
inline void __linear_insert(_RandomAccessIter __first,
_RandomAccessIter __last, _Tp*) {
_Tp __val = *__last;//记录尾元素
if (__val < *__first) {//尾元素比头元素还小
//将整个区间向右移一个位置
copy_backward(__first, __last, __last + 1);
*__first = __val;//令头元素等于原先的尾元素
//以上两行命令的功能相等于交换两个元素
}
else//尾元素不小于头元素
__unguarded_linear_insert(__last, __val);
}
//__insertion_sort版本号二的辅助函数
template <class _RandomAccessIter, class _Tp, class _Compare>
inline void __linear_insert(_RandomAccessIter __first,
_RandomAccessIter __last, _Tp*, _Compare __comp) {
_Tp __val = *__last;
if (__comp(__val, *__first)) {
copy_backward(__first, __last, __last + 1);
*__first = __val;
}
else
__unguarded_linear_insert(__last, __val, __comp);
}
//__insertion_sort以双层循环形式进行。 外循环遍历整个序列。每次迭代决定出一个子区间;
//内循环遍历子区间,将子区间内的每个“逆转对”倒转过来,假设一旦不存在“逆转对”。表示排序完成。
//“逆转对”概念:指不论什么两个迭代器i和j。i<j,而*i>*j.
//版本号一
template <class _RandomAccessIter>
void __insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) {
if (__first == __last) return; //若区间为空,则退出
for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)//外循环,遍历整个区间
//[first,i)形成的子空间
__linear_insert(__first, __i, __VALUE_TYPE(__first));
}
//版本号二
template <class _RandomAccessIter, class _Compare>
void __insertion_sort(_RandomAccessIter __first,
_RandomAccessIter __last, _Compare __comp) {
if (__first == __last) return;
for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
__linear_insert(__first, __i, __VALUE_TYPE(__first), __comp);
} template <class _RandomAccessIter, class _Tp>
void __unguarded_insertion_sort_aux(_RandomAccessIter __first,
_RandomAccessIter __last, _Tp*) {
for (_RandomAccessIter __i = __first; __i != __last; ++__i)
__unguarded_linear_insert(__i, _Tp(*__i));
}
//sort版本号一的辅助函数
template <class _RandomAccessIter>
inline void __unguarded_insertion_sort(_RandomAccessIter __first,
_RandomAccessIter __last) {
__unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first));
} 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(__i, _Tp(*__i), __comp);
} template <class _RandomAccessIter, class _Compare>
inline void __unguarded_insertion_sort(_RandomAccessIter __first,
_RandomAccessIter __last,
_Compare __comp) {
__unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first),
__comp);
}
//sort版本号一的辅助函数
template <class _RandomAccessIter>
void __final_insertion_sort(_RandomAccessIter __first,
_RandomAccessIter __last) {
if (__last - __first > __stl_threshold) {//推断元素个数是否大于16
//则把区间切割成两段,一端长度为16。还有一端为剩余的长度
__insertion_sort(__first, __first + __stl_threshold);
__unguarded_insertion_sort(__first + __stl_threshold, __last);
}
else//若不大于16,直接调用插入排序
__insertion_sort(__first, __last);
} template <class _RandomAccessIter, class _Compare>
void __final_insertion_sort(_RandomAccessIter __first,
_RandomAccessIter __last, _Compare __comp) {
if (__last - __first > __stl_threshold) {
__insertion_sort(__first, __first + __stl_threshold, __comp);
__unguarded_insertion_sort(__first + __stl_threshold, __last, __comp);
}
else
__insertion_sort(__first, __last, __comp);
}
//_lg()函数是用来控制切割恶化的情况
//该函数找出2^k <= n 的最大值k;
//比如:n=7,得k=2; n=20,得k=4; n=8,得k=3;
template <class _Size>
inline _Size __lg(_Size __n) {
_Size __k;
for (__k = 0; __n != 1; __n >>= 1) ++__k;
return __k;
}
//sort版本号一的辅助函数
//參数__depth_limit表示最大的切割层数
template <class _RandomAccessIter, class _Tp, class _Size>
void __introsort_loop(_RandomAccessIter __first,
_RandomAccessIter __last, _Tp*,
_Size __depth_limit)
{
//__stl_threshold为全局常量。其值为16
while (__last - __first > __stl_threshold) {//若区间长度大于16
if (__depth_limit == 0) {//表示切割恶化
partial_sort(__first, __last, __last);//转而调用堆排序heap_sort()
return;
}
--__depth_limit;
//计算切割点cut,枢纽值是採用首、尾、*三个的中间值
_RandomAccessIter __cut =
__unguarded_partition(__first, __last,
_Tp(__median(*__first,
*(__first + (__last - __first)/2),
*(__last - 1))));
//对右半部分递归地进行排序
__introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit);
__last = __cut;//接下来对左半部分递归地进行排序
}
} template <class _RandomAccessIter, class _Tp, class _Size, class _Compare>
void __introsort_loop(_RandomAccessIter __first,
_RandomAccessIter __last, _Tp*,
_Size __depth_limit, _Compare __comp)
{
while (__last - __first > __stl_threshold) {
if (__depth_limit == 0) {
partial_sort(__first, __last, __last, __comp);
return;
}
--__depth_limit;
_RandomAccessIter __cut =
__unguarded_partition(__first, __last,
_Tp(__median(*__first,
*(__first + (__last - __first)/2),
*(__last - 1), __comp)),
__comp);
__introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit, __comp);
__last = __cut;
}
}
//SGI STL的排序算法,迭代器參数的类型必须是随机訪问迭代器_RandomAccessIter
/*
函数功能:Sorts the elements in the range [first,last) into ascending order.
函数原型:
default (1) :版本号一採用默认的operator<
template <class RandomAccessIterator>
void sort (RandomAccessIterator first, RandomAccessIterator last);
custom (2) :版本号二採用仿函数comp
template <class RandomAccessIterator, class Compare>
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
*/
//版本号一
template <class _RandomAccessIter>
inline void sort(_RandomAccessIter __first, _RandomAccessIter __last) {
__STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
__STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type,
_LessThanComparable);
//_lg()函数是用来控制切割恶化的情况
if (__first != __last) {
__introsort_loop(__first, __last,
__VALUE_TYPE(__first),
__lg(__last - __first) * 2);
//进行插入排序
__final_insertion_sort(__first, __last);
}
}
//版本号二
template <class _RandomAccessIter, class _Compare>
inline void sort(_RandomAccessIter __first, _RandomAccessIter __last,
_Compare __comp) {
__STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
__STL_BINARY_FUNCTION_CHECK(_Compare, bool,
typename iterator_traits<_RandomAccessIter>::value_type,
typename iterator_traits<_RandomAccessIter>::value_type);
if (__first != __last) {
__introsort_loop(__first, __last,
__VALUE_TYPE(__first),
__lg(__last - __first) * 2,
__comp);
__final_insertion_sort(__first, __last, __comp);
}
} // stable_sort() and its auxiliary functions. template <class _RandomAccessIter>
void __inplace_stable_sort(_RandomAccessIter __first,
_RandomAccessIter __last) {
if (__last - __first < 15) {
__insertion_sort(__first, __last);
return;
}
_RandomAccessIter __middle = __first + (__last - __first) / 2;
__inplace_stable_sort(__first, __middle);
__inplace_stable_sort(__middle, __last);
__merge_without_buffer(__first, __middle, __last,
__middle - __first,
__last - __middle);
} template <class _RandomAccessIter, class _Compare>
void __inplace_stable_sort(_RandomAccessIter __first,
_RandomAccessIter __last, _Compare __comp) {
if (__last - __first < 15) {
__insertion_sort(__first, __last, __comp);
return;
}
_RandomAccessIter __middle = __first + (__last - __first) / 2;
__inplace_stable_sort(__first, __middle, __comp);
__inplace_stable_sort(__middle, __last, __comp);
__merge_without_buffer(__first, __middle, __last,
__middle - __first,
__last - __middle,
__comp);
} template <class _RandomAccessIter1, class _RandomAccessIter2,
class _Distance>
void __merge_sort_loop(_RandomAccessIter1 __first,
_RandomAccessIter1 __last,
_RandomAccessIter2 __result, _Distance __step_size) {
_Distance __two_step = 2 * __step_size; while (__last - __first >= __two_step) {
__result = merge(__first, __first + __step_size,
__first + __step_size, __first + __two_step,
__result);
__first += __two_step;
} __step_size = min(_Distance(__last - __first), __step_size);
merge(__first, __first + __step_size, __first + __step_size, __last,
__result);
} template <class _RandomAccessIter1, class _RandomAccessIter2,
class _Distance, class _Compare>
void __merge_sort_loop(_RandomAccessIter1 __first,
_RandomAccessIter1 __last,
_RandomAccessIter2 __result, _Distance __step_size,
_Compare __comp) {
_Distance __two_step = 2 * __step_size; while (__last - __first >= __two_step) {
__result = merge(__first, __first + __step_size,
__first + __step_size, __first + __two_step,
__result,
__comp);
__first += __two_step;
}
__step_size = min(_Distance(__last - __first), __step_size); merge(__first, __first + __step_size,
__first + __step_size, __last,
__result,
__comp);
} const int __stl_chunk_size = 7; template <class _RandomAccessIter, class _Distance>
void __chunk_insertion_sort(_RandomAccessIter __first,
_RandomAccessIter __last, _Distance __chunk_size)
{
while (__last - __first >= __chunk_size) {
__insertion_sort(__first, __first + __chunk_size);
__first += __chunk_size;
}
__insertion_sort(__first, __last);
} template <class _RandomAccessIter, class _Distance, class _Compare>
void __chunk_insertion_sort(_RandomAccessIter __first,
_RandomAccessIter __last,
_Distance __chunk_size, _Compare __comp)
{
while (__last - __first >= __chunk_size) {
__insertion_sort(__first, __first + __chunk_size, __comp);
__first += __chunk_size;
}
__insertion_sort(__first, __last, __comp);
} template <class _RandomAccessIter, class _Pointer, class _Distance>
void __merge_sort_with_buffer(_RandomAccessIter __first,
_RandomAccessIter __last,
_Pointer __buffer, _Distance*) {
_Distance __len = __last - __first;
_Pointer __buffer_last = __buffer + __len; _Distance __step_size = __stl_chunk_size;
__chunk_insertion_sort(__first, __last, __step_size); while (__step_size < __len) {
__merge_sort_loop(__first, __last, __buffer, __step_size);
__step_size *= 2;
__merge_sort_loop(__buffer, __buffer_last, __first, __step_size);
__step_size *= 2;
}
} template <class _RandomAccessIter, class _Pointer, class _Distance,
class _Compare>
void __merge_sort_with_buffer(_RandomAccessIter __first,
_RandomAccessIter __last, _Pointer __buffer,
_Distance*, _Compare __comp) {
_Distance __len = __last - __first;
_Pointer __buffer_last = __buffer + __len; _Distance __step_size = __stl_chunk_size;
__chunk_insertion_sort(__first, __last, __step_size, __comp); while (__step_size < __len) {
__merge_sort_loop(__first, __last, __buffer, __step_size, __comp);
__step_size *= 2;
__merge_sort_loop(__buffer, __buffer_last, __first, __step_size, __comp);
__step_size *= 2;
}
} template <class _RandomAccessIter, class _Pointer, class _Distance>
void __stable_sort_adaptive(_RandomAccessIter __first,
_RandomAccessIter __last, _Pointer __buffer,
_Distance __buffer_size) {
_Distance __len = (__last - __first + 1) / 2;
_RandomAccessIter __middle = __first + __len;
if (__len > __buffer_size) {
__stable_sort_adaptive(__first, __middle, __buffer, __buffer_size);
__stable_sort_adaptive(__middle, __last, __buffer, __buffer_size);
}
else {
__merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0);
__merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0);
}
__merge_adaptive(__first, __middle, __last, _Distance(__middle - __first),
_Distance(__last - __middle), __buffer, __buffer_size);
} template <class _RandomAccessIter, class _Pointer, class _Distance,
class _Compare>
void __stable_sort_adaptive(_RandomAccessIter __first,
_RandomAccessIter __last, _Pointer __buffer,
_Distance __buffer_size, _Compare __comp) {
_Distance __len = (__last - __first + 1) / 2;
_RandomAccessIter __middle = __first + __len;
if (__len > __buffer_size) {
__stable_sort_adaptive(__first, __middle, __buffer, __buffer_size,
__comp);
__stable_sort_adaptive(__middle, __last, __buffer, __buffer_size,
__comp);
}
else {
__merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0,
__comp);
__merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0,
__comp);
}
__merge_adaptive(__first, __middle, __last, _Distance(__middle - __first),
_Distance(__last - __middle), __buffer, __buffer_size,
__comp);
} template <class _RandomAccessIter, class _Tp, class _Distance>
inline void __stable_sort_aux(_RandomAccessIter __first,
_RandomAccessIter __last, _Tp*, _Distance*) {
_Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last);
if (buf.begin() == 0)
__inplace_stable_sort(__first, __last);
else
__stable_sort_adaptive(__first, __last, buf.begin(),
_Distance(buf.size()));
} template <class _RandomAccessIter, class _Tp, class _Distance, class _Compare>
inline void __stable_sort_aux(_RandomAccessIter __first,
_RandomAccessIter __last, _Tp*, _Distance*,
_Compare __comp) {
_Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last);
if (buf.begin() == 0)
__inplace_stable_sort(__first, __last, __comp);
else
__stable_sort_adaptive(__first, __last, buf.begin(),
_Distance(buf.size()),
__comp);
} template <class _RandomAccessIter>
inline void stable_sort(_RandomAccessIter __first,
_RandomAccessIter __last) {
__STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
__STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type,
_LessThanComparable);
__stable_sort_aux(__first, __last,
__VALUE_TYPE(__first),
__DISTANCE_TYPE(__first));
} template <class _RandomAccessIter, class _Compare>
inline void stable_sort(_RandomAccessIter __first,
_RandomAccessIter __last, _Compare __comp) {
__STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
__STL_BINARY_FUNCTION_CHECK(_Compare, bool,
typename iterator_traits<_RandomAccessIter>::value_type,
typename iterator_traits<_RandomAccessIter>::value_type);
__stable_sort_aux(__first, __last,
__VALUE_TYPE(__first),
__DISTANCE_TYPE(__first),
__comp);
} // partial_sort, partial_sort_copy, and auxiliary functions.
//又一次安排序列[first,last),使序列前半部分middle-first个最小元素以递增顺序排序,并将其置于[first,middle)
//其余last-middle个元素不指定不论什么排序。并将其置于[middle,last)
//注意:迭代器middle是在[first,last)范围之内 /*
函数功能:Rearranges the elements in the range [first,last),
in such a way that the elements before middle are the smallest elements in the entire range
and are sorted in ascending order, while the remaining elements are left without any specific order. 函数原型:
default (1) 版本号一 operator<
template <class RandomAccessIterator>
void partial_sort (RandomAccessIterator first, RandomAccessIterator middle,
RandomAccessIterator last);
custom (2) 版本号二 comp
template <class RandomAccessIterator, class Compare>
void partial_sort (RandomAccessIterator first, RandomAccessIterator middle,
RandomAccessIterator last, Compare comp);
*/ template <class _RandomAccessIter, class _Tp>
void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle,
_RandomAccessIter __last, _Tp*) {
//利用heap的知识,在SGI STL中,是採用最大堆
//将[first,middle)区间的元素创建成最大堆
//再依据最大堆的性质。一个一个弹出堆,并将其保存。即堆排序
make_heap(__first, __middle);//创建最大堆,定义与<stl_heap.h>文件
//下面是在区间中[first,last)找出middle-first个最小元素
//这里的是将后半部分[middle,last)的元素依次与最大堆的根节点元素(即堆的最大元素)比較
//若小于堆的最大元素,则与堆的最大元素交换,并调整堆,使其依次成为最大堆
//若不小于堆的最大元素。则不作不论什么操作
for (_RandomAccessIter __i = __middle; __i < __last; ++__i)
if (*__i < *__first)
__pop_heap(__first, __middle, __i, _Tp(*__i),
__DISTANCE_TYPE(__first));
sort_heap(__first, __middle);//对最大堆进行堆排序
}
//版本号一
template <class _RandomAccessIter>
inline void partial_sort(_RandomAccessIter __first,
_RandomAccessIter __middle,
_RandomAccessIter __last) {
__STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
__STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type,
_LessThanComparable);
__partial_sort(__first, __middle, __last, __VALUE_TYPE(__first));
} template <class _RandomAccessIter, class _Tp, class _Compare>
void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle,
_RandomAccessIter __last, _Tp*, _Compare __comp) {
make_heap(__first, __middle, __comp);
for (_RandomAccessIter __i = __middle; __i < __last; ++__i)
if (__comp(*__i, *__first))
__pop_heap(__first, __middle, __i, _Tp(*__i), __comp,
__DISTANCE_TYPE(__first));
sort_heap(__first, __middle, __comp);
}
//版本号二
template <class _RandomAccessIter, class _Compare>
inline void partial_sort(_RandomAccessIter __first,
_RandomAccessIter __middle,
_RandomAccessIter __last, _Compare __comp) {
__STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
__STL_BINARY_FUNCTION_CHECK(_Compare, bool,
typename iterator_traits<_RandomAccessIter>::value_type,
typename iterator_traits<_RandomAccessIter>::value_type);
__partial_sort(__first, __middle, __last, __VALUE_TYPE(__first), __comp);
}
//partial_sort_copy与partial_sort的实现机制是同样,仅仅是partial_sort_copy将元素排序后放在以result起始的容器中
template <class _InputIter, class _RandomAccessIter, class _Distance,
class _Tp>
_RandomAccessIter __partial_sort_copy(_InputIter __first,
_InputIter __last,
_RandomAccessIter __result_first,
_RandomAccessIter __result_last,
_Distance*, _Tp*) {
if (__result_first == __result_last) return __result_last;
_RandomAccessIter __result_real_last = __result_first;
while(__first != __last && __result_real_last != __result_last) {
*__result_real_last = *__first;
++__result_real_last;
++__first;
}
make_heap(__result_first, __result_real_last);
while (__first != __last) {
if (*__first < *__result_first)
__adjust_heap(__result_first, _Distance(0),
_Distance(__result_real_last - __result_first),
_Tp(*__first));
++__first;
}
sort_heap(__result_first, __result_real_last);
return __result_real_last;
} template <class _InputIter, class _RandomAccessIter>
inline _RandomAccessIter
partial_sort_copy(_InputIter __first, _InputIter __last,
_RandomAccessIter __result_first,
_RandomAccessIter __result_last) {
__STL_REQUIRES(_InputIter, _InputIterator);
__STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
__STL_CONVERTIBLE(typename iterator_traits<_InputIter>::value_type,
typename iterator_traits<_RandomAccessIter>::value_type);
__STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type,
_LessThanComparable);
__STL_REQUIRES(typename iterator_traits<_InputIter>::value_type,
_LessThanComparable);
return __partial_sort_copy(__first, __last, __result_first, __result_last,
__DISTANCE_TYPE(__result_first),
__VALUE_TYPE(__first));
} template <class _InputIter, class _RandomAccessIter, class _Compare,
class _Distance, class _Tp>
_RandomAccessIter __partial_sort_copy(_InputIter __first,
_InputIter __last,
_RandomAccessIter __result_first,
_RandomAccessIter __result_last,
_Compare __comp, _Distance*, _Tp*) {
if (__result_first == __result_last) return __result_last;
_RandomAccessIter __result_real_last = __result_first;
while(__first != __last && __result_real_last != __result_last) {
*__result_real_last = *__first;
++__result_real_last;
++__first;
}
make_heap(__result_first, __result_real_last, __comp);
while (__first != __last) {
if (__comp(*__first, *__result_first))
__adjust_heap(__result_first, _Distance(0),
_Distance(__result_real_last - __result_first),
_Tp(*__first),
__comp);
++__first;
}
sort_heap(__result_first, __result_real_last, __comp);
return __result_real_last;
} template <class _InputIter, class _RandomAccessIter, class _Compare>
inline _RandomAccessIter
partial_sort_copy(_InputIter __first, _InputIter __last,
_RandomAccessIter __result_first,
_RandomAccessIter __result_last, _Compare __comp) {
__STL_REQUIRES(_InputIter, _InputIterator);
__STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
__STL_CONVERTIBLE(typename iterator_traits<_InputIter>::value_type,
typename iterator_traits<_RandomAccessIter>::value_type);
__STL_BINARY_FUNCTION_CHECK(_Compare, bool,
typename iterator_traits<_RandomAccessIter>::value_type,
typename iterator_traits<_RandomAccessIter>::value_type);
return __partial_sort_copy(__first, __last, __result_first, __result_last,
__comp,
__DISTANCE_TYPE(__result_first),
__VALUE_TYPE(__first));
}
// nth_element() and its auxiliary functions.
//nth_element版本号一辅助函数
template <class _RandomAccessIter, class _Tp>
void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
_RandomAccessIter __last, _Tp*) {
while (__last - __first > 3) {//区间长度大于3
//获取切割点cut
_RandomAccessIter __cut =
__unguarded_partition(__first, __last,
_Tp(__median(*__first,
*(__first + (__last - __first)/2),
*(__last - 1))));
if (__cut <= __nth)//若切割点小于指定位置,则nth位置在右半段
__first = __cut;//再对右半段进行切割
else //否则,对左半段进行切割
__last = __cut;
}
__insertion_sort(__first, __last);
}
//又一次排序序列[first,last),使迭代器nth所指的元素。与“整个[first,last)序列完整排序后,同一位置的元素”同值.
//此外,必须保证[nth,last)内的全部元素不小于[first,nth)内的元素,可是对于序列[first,nth)和序列[nth,last)内的元素的排序顺序不能确定. /*
函数功能:Rearranges the elements in the range [first,last),
in such a way that the element at the nth position is the element that would be in that position in a sorted sequence.
函数原型:
default (1)
template <class RandomAccessIterator>
void nth_element (RandomAccessIterator first, RandomAccessIterator nth,
RandomAccessIterator last);
custom (2)
template <class RandomAccessIterator, class Compare>
void nth_element (RandomAccessIterator first, RandomAccessIterator nth,
RandomAccessIterator last, Compare comp);
*/
//nth_element版本号一
template <class _RandomAccessIter>
inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
_RandomAccessIter __last) {
__STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
__STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type,
_LessThanComparable);
__nth_element(__first, __nth, __last, __VALUE_TYPE(__first));
} template <class _RandomAccessIter, class _Tp, class _Compare>
void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
_RandomAccessIter __last, _Tp*, _Compare __comp) {
while (__last - __first > 3) {
_RandomAccessIter __cut =
__unguarded_partition(__first, __last,
_Tp(__median(*__first,
*(__first + (__last - __first)/2),
*(__last - 1),
__comp)),
__comp);
if (__cut <= __nth)
__first = __cut;
else
__last = __cut;
}
__insertion_sort(__first, __last, __comp);
} template <class _RandomAccessIter, class _Compare>
inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
_RandomAccessIter __last, _Compare __comp) {
__STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
__STL_BINARY_FUNCTION_CHECK(_Compare, bool,
typename iterator_traits<_RandomAccessIter>::value_type,
typename iterator_traits<_RandomAccessIter>::value_type);
__nth_element(__first, __nth, __last, __VALUE_TYPE(__first), __comp);
} // is_sorted, a predicated testing whether a range is sorted in
// nondescending order. This is an extension, not part of the C++
// standard. template <class _ForwardIter>
bool is_sorted(_ForwardIter __first, _ForwardIter __last)
{
__STL_REQUIRES(_ForwardIter, _ForwardIterator);
__STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type,
_LessThanComparable);
if (__first == __last)
return true; _ForwardIter __next = __first;
for (++__next; __next != __last; __first = __next, ++__next) {
if (*__next < *__first)
return false;
} return true;
} template <class _ForwardIter, class _StrictWeakOrdering>
bool is_sorted(_ForwardIter __first, _ForwardIter __last,
_StrictWeakOrdering __comp)
{
__STL_REQUIRES(_ForwardIter, _ForwardIterator);
__STL_BINARY_FUNCTION_CHECK(_StrictWeakOrdering, bool,
typename iterator_traits<_ForwardIter>::value_type,
typename iterator_traits<_ForwardIter>::value_type);
if (__first == __last)
return true; _ForwardIter __next = __first;
for (++__next; __next != __last; __first = __next, ++__next) {
if (__comp(*__next, *__first))
return false;
} return true;
}

參考资料:

《STL源代码分析》侯杰

版权声明:本文博客原创文章,博客,未经同意,不得转载。

STL源代码分析——STL算法sort排序算法的更多相关文章

  1. STL源代码分析——STL算法merge合并算法

    前言 因为在前文的<STL算法剖析>中.源代码剖析许多.不方便学习.也不方便以后复习,这里把这些算法进行归类.对他们单独的源代码剖析进行解说.本文介绍的STL算法中的merge合并算法. ...

  2. STL源代码分析——STL算法remove删除算法

    前言 因为在前文的<STL算法剖析>中,源代码剖析许多.不方便学习,也不方便以后复习,这里把这些算法进行归类.对他们单独的源代码剖析进行解说.本文介绍的STL算法中的remove删除算法. ...

  3. STL中sort排序算法第三个参数&lowbar;Compare的实现本质

    关于C++ STL vector 中的sort排序算法有三种自定义实现,它们本质上都是返回bool类型,提供给sort函数作为第三个参数. 重载运算符 全局的比较函数 函数对象 我认为从实现方式看,重 ...

  4. javascript数据结构与算法--高级排序算法

    javascript数据结构与算法--高级排序算法 高级排序算法是处理大型数据集的最高效排序算法,它是处理的数据集可以达到上百万个元素,而不仅仅是几百个或者几千个.现在我们来学习下2种高级排序算法-- ...

  5. 在Object-C中学习数据结构与算法之排序算法

    笔者在学习数据结构与算法时,尝试着将排序算法以动画的形式呈现出来更加方便理解记忆,本文配合Demo 在Object-C中学习数据结构与算法之排序算法阅读更佳. 目录 选择排序 冒泡排序 插入排序 快速 ...

  6. c&sol;c&plus;&plus; 通用的(泛型)算法 之 只读算法,写算法,排序算法

    通用的(泛型)算法 之 只读算法,写算法,排序算法 只读算法: 函数名 功能描述 accumulate 求容器里元素的和 equal 比较2个容器里的元素 写算法 函数名 功能描述 fill 用给定值 ...

  7. javascript数据结构与算法--基本排序算法(冒泡、选择、排序)及效率比较

    javascript数据结构与算法--基本排序算法(冒泡.选择.排序)及效率比较 一.数组测试平台. javascript数据结构与算法--基本排序(封装基本数组的操作),封装常规数组操作的函数,比如 ...

  8. javascript数据结构与算法--高级排序算法(快速排序法,希尔排序法)

    javascript数据结构与算法--高级排序算法(快速排序法,希尔排序法) 一.快速排序算法 /* * 这个函数首先检查数组的长度是否为0.如果是,那么这个数组就不需要任何排序,函数直接返回. * ...

  9. JS中算法之排序算法

    1.基本排序算法 1.1.冒泡排序 它是最慢的排序算法之一. 1.不断比较相邻的两个元素,如果前一个比后一个大,则交换位置. 2.当比较完第一轮的时候最后一个元素应该是最大的一个. 3.按照步骤一的方 ...

随机推荐

  1. Android 笔记 AutoCompleteTextView day8

    用于自动补全内容 适应器可用于显示多行内容 package com.supermario.autocompletedemo; import android.app.Activity; import a ...

  2. vim编辑器的使用

    I 在光标所在行的行首插入 A 在光标所在行的行尾插入 { 移动到上一段 } 移动到下一段 空格向后移动一格 H 屏幕顶部 M 屏幕中间 L 屏幕下方 n| 使光标移动到第几个字符处 ngg 移动到制 ...

  3. Failed to resolve&colon; junit&colon;junit&colon;4&period;12

    在Android Studio创建项目之后,提示一个junit错误. 解决方案: 第一步:找到build.gradle的file,如图:  第二步: 第三步:把中间行代码"testCompi ...

  4. NET 框架基本原理透析⑵

    生成.打包.部署及管理应用程序与类型 要生成就离不开程,序集,程序集是包含一个或多个类型定义文件和资源文件的集合.在程序集包含的所有文件中,有一个文件用于保存清单.清单是另外一组元数据表的集合,其中主 ...

  5. &lbrack;MFC&rsqb; MFC音乐播放器 傻瓜级教程 网络 搜索歌曲 下载

    >目录< >——————————————————————< 1.建立工程  1.建立一个MFC工程,命名为Tao_Music 2.选择为基本对话框 3.包含Windows So ...

  6. 谈Mysql索引

    myisam和innodb的索引有什么区别? 两个索引都是B+树索引,但是myisam的表存储和索引存储是分开的,索引存储中存放的是表的地址.而innodb表存储本身就是一个B+树,它是用主键来做B+ ...

  7. ServletRequest中getReader&lpar;&rpar;和getInputStream&lpar;&rpar;只能调用一次的解决办法

    转载:http://blog.sina.com.cn/s/blog_870cd7b90101fg58.html 最近使用spring mvc做项目,数据格式是json,有一个功能是实现记录请求的参数, ...

  8. JS调用Delphi编写的OCX控件

    原文:http://www.mamicode.com/info-detail-471283.html 一.使用Delphi XE2编写OCX控件 生成OCX工程: 1.File-New-Other,在 ...

  9. Python操作 Memcache、Redis、RabbitMQ

    Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度 ...

  10. ps切图技巧

    步骤1: ps打开psd文件 步骤2: 点击移动工具,观察左上角的自动选择是否有勾选 ,如果没有最好勾选,对应的选项有图层和组,善于切换这个功能能够有效快速的找到你要的区域 步骤3: 找到要切图的元素 ...