• 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
  • 相关阅读:
    剑指Offer_08_跳台阶
    剑指Offer_07_斐波那契数列
    HDU 4283 You Are the One
    1B. Spreadsheets
    1A Theatre Square
    HDU 2476 String painter(记忆化搜索, DP)
    LightOJ 1422 Halloween Costumes(记忆化搜索)
    POJ 1651 Multiplication PuzzleDP方法:
    POJ 2955 Brackets (区间DP)
    HDU 5452 Minimum Cut
  • 原文地址:https://www.cnblogs.com/runnyu/p/6008819.html
Copyright © 2020-2023  润新知