STL源码剖析(算法)

Posted Runnyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STL源码剖析(算法)相关的知识,希望对你有一定的参考价值。

STL中算法是基于迭代器来实现的。

有了容器中迭代器的实现(对operator*、operator++等的重载),STL中大部分算法实现就显得很简单了。

先看一例关于find算法的实现:

 1 template <class InputIterator, class T>
 2 InputIterator find(InputIterator first, InputIterator last, const T& value) {
 3     // 直接利用iterator中的operator++、operator*、operator!=实现
 4     // 默认使用class T的operator!=
 5     while (first != last && *first != value) ++first; 
 6         return first;
 7 }
 8 
 9 template <class InputIterator, class Predicate>
10 InputIterator find_if(InputIterator first, InputIterator last,
11                       Predicate pred) {
12     // 能接受一个仿函数 用来指定find的条件
13     while (first != last && !pred(*first)) ++first;
14         return first;
15 }
View Code

其它的基本算法实现都差不多,它们一般只是执行单纯的数据移动、线性查找、计数、循环遍历等操作。

比较复杂的算法一般都关于排列、排序之类的,这次只要说说SGI STL中sort()的实现。

 

SGI STL中的sort()

SGI STL中的排序算法混合了quick sort、heap sort、insert sort三种排序算法。

总体上用的是quick sort,分割到一定深度(2^k < = n)的时候会使用heap sort,

在分割区域元素大小小于阀值(16)时最后执行的是insert sort。

下面是sort()的的基本框架:

 1 template <class RandomAccessIterator>
 2 inline void sort(RandomAccessIterator first, RandomAccessIterator last) {
 3     if (first != last) {
 4         // 使用quick sort、heap sort排序 直到所有分割区域元素大小都小于阀值 __stl_threshold = 16
 5         __introsort_loop(first, last, value_type(first), __lg(last - first) * 2);
 6        // 最后对其分割区域都执行一次insert sort
 7         __final_insertion_sort(first, last);
 8     }
 9 }
10 
11 // 阀值k满足2^k <= n
12 template <class Size>
13 inline Size __lg(Size n) {
14     Size k;
15     for (k = 0; n > 1; n >>= 1) ++k;
16     return k;
17 }
View Code

然后看看introsort_loop的实现:

 1 template <class RandomAccessIterator, class T, class Size>
 2 void __introsort_loop(RandomAccessIterator first,
 3                       RandomAccessIterator last, T*,
 4                       Size depth_limit) {
 5     while (last - first > __stl_threshold) { // 元素足够少  返回由insert sort处理
 6         if (depth_limit == 0) {  // 分割恶化 采用heap_sort
 7             partial_sort(first, last, last);  // 实现为heap_sort
 8             return;
 9         }
10         // 深度
11         --depth_limit;
12         // key为first middle last的中值
13         RandomAccessIterator cut = __unguarded_partition
14            (first, last, T(__median(*first, *(first + (last - first)/2),
15                                *(last - 1))));
16         // 递归的处理[cut, last)
17         __introsort_loop(cut, last, value_type(first), depth_limit);
18         // 返回while 继续处理[first, cut)
19         last = cut;
20     }
21 }
View Code

以上是关于STL源码剖析(算法)的主要内容,如果未能解决你的问题,请参考以下文章

STL源码剖析

stl源码剖析学习笔记traits编程技法简明例程

《STL源码剖析》相关面试题总结

STL源码剖析(迭代器)

STL源码剖析(中文完整版)pdf

《STL源码剖析》——第六:关联容器与算法