STL算的中的sort接受两个RandomAcceddIterators(随机存取迭代器)。STL的所有关系型容器都拥有自动排序功能(底层采用RB-tree),所有不需要用到sort算法。至于序列式容器stack,queue和priority-queue都有特别的出入口,不允许用户对元素排序。剩下的vector、deque和list,前两者的迭代器满足要求适合用sort算法。而list的迭代器属于BidirectionalIterators,不适合sort算法。如果要对list排序,可以使用它自己通过的成员函数sort()算法。
SGI STL的sort算法,数据量大时采用QuickSort,分段递归排序。一旦分段后的数据量小于某个门槛,为避免QuickSort的递归调用带来过大的额外负荷,就改用Insertion Sort。如果递归层次过深,还会改用Heap Sort。SGI将使用快排与插入排序的分割线设为16。
RW STL的sort算法,数据大的时候用QuickSort,小的时候用Insertion Sort。
下面是SGI STL sort的源码:
// 版本一 // 千萬注意:sort()只適用於 RandomAccessIterator template <class RandomAccessIterator> inline void sort(RandomAccessIterator first, RandomAccessIterator last) { if (first != last) { __introsort_loop(first, last, value_type(first), __lg(last - first) * 2); __final_insertion_sort(first, last); } } // 版本一 // 注意,本函式內的許多迭代器運算動作,都只適用於RandomAccess Iterators. template <class RandomAccessIterator, class T, class Size> void __introsort_loop(RandomAccessIterator first, RandomAccessIterator last, T*, Size depth_limit) { // 以下,__stl_threshold 是個全域常數,稍早定義為 const int 16。 while (last - first > __stl_threshold) { if (depth_limit == 0) { // 至此,切割惡化 partial_sort(first, last, last); // 改用 heapsort return; } --depth_limit; // 以下是 median-of-three partition,選擇一個夠好的樞軸並決定切割點。 // 切割點將落在迭代器 cut 身上。 RandomAccessIterator cut = __unguarded_partition (first, last, T(__median(*first, *(first + (last - first)/2), *(last - 1)))); // 對右半段遞迴進行 sort. __introsort_loop(cut, last, value_type(first), depth_limit); last = cut; // 現在回到while 迴圈,準備對左半段遞迴進行 sort. // 這種寫法可讀性較差,效率並沒有比較好。 // RW STL 採用一般教科書寫法(直觀地對左半段和右半段遞迴),較易閱讀。 } } template <class RandomAccessIterator> void __final_insertion_sort(RandomAccessIterator first, RandomAccessIterator last) { if (last - first > __stl_threshold) { __insertion_sort(first, first + __stl_threshold); __unguarded_insertion_sort(first + __stl_threshold, last); } else __insertion_sort(first, last); } template <class RandomAccessIterator> void __insertion_sort(RandomAccessIterator first, RandomAccessIterator last) { if (first == last) return; for (RandomAccessIterator i = first + 1; i != last; ++i) // 外迴圈 __linear_insert(first, i, value_type(first)); // first,i形成一個子範圍 } // 版本一 template <class RandomAccessIterator, class T> inline void __linear_insert(RandomAccessIterator first, RandomAccessIterator last, T*) { T value = *last; // 記錄尾元素 if (value < *first) { // 尾比頭還小(那就別一個個比較了,一次做完…) copy_backward(first, last, last + 1); // 將整個範圍向右遞移一個位置 *first = value; // 令頭元素等於原先的尾元素值 } else __unguarded_linear_insert(last, value); } // 版本一 template <class RandomAccessIterator, class T> void __unguarded_linear_insert(RandomAccessIterator last, T value) { RandomAccessIterator next = last; --next; // insertion sort 的內迴圈 // 注意,一旦不出現逆轉對(inversion),迴圈就可以結束了。 while (value < *next) { // 逆轉對(inversion)存在 *last = *next; // 轉正 last = next; // 調整迭代器 --next; // 前進一個位置 } *last = value; } // 版本一 template <class RandomAccessIterator> inline void __unguarded_insertion_sort(RandomAccessIterator first, RandomAccessIterator last) { __unguarded_insertion_sort_aux(first, last, value_type(first)); } template <class RandomAccessIterator, class T> void __unguarded_insertion_sort_aux(RandomAccessIterator first, RandomAccessIterator last, T*) { for (RandomAccessIterator i = first; i != last; ++i) __unguarded_linear_insert(i, T(*i)); }
原文:http://blog.csdn.net/walkerkalr/article/details/23833049