6.7.9 sort
STL的所有关系型容器(set,map,multiset……)都拥有自动排序功能(底层结构采用RB-tree),不需要sort算法。序列式容器stack、queue和priority-queue不允许排序。剩下的vector、deque和list,前两个适合使用sort排序,list迭代器不属于随机存取迭代器,不适合使用sort排序。
STL的sort算法,数据量大时采用快速排序,分段递归排序。一旦分段后的数据量小于某个门槛,为避免快排的递归调用带来过大的额外负荷就采用插入排序。如果递归层次过深,还会采用堆排序。
Insertion Sort
插入排序算法,__insertion_sort以双层循环形式进行。外循环遍历整个序列,每次迭代决定出一个子区间;内循环遍历子区间,将子区间内的每一个“逆转对”倒转过来,如果一旦不存在“逆转对”,表示排序完毕。
“逆转对”概念:指任何两个迭代器i和j,i<j,而*i>*j.
// 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 =