STL源码剖析读后知识点整理

容器

序列式容器

vector

list

list中的merge函数输入的前提是两个list都是已经排序的,源码中每次从两个list遍历比较,如果第二的节点比第一个节点小,则将其插入第一个节点前。
考虑到已经排序的节点,第二个list中节点有可能连续几个都比第一个节点小,是不是可以将其一段插入,而不是每次比较后插入一个节点。
举例,a为第一list,ai为第一list的第i个节点,b为第二list,bi为第二list的第i节点;b1,b2,b3都小于a1,源码的做法是将其一个个插入a1前。是不是可以将b1,b2,b3一起插入a1前,减少插入节点的次数。
以下是SGI_STL的源码,注释部分为我觉得可以改进的地方。

template<class _Tp, class _Alloc>
void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x){
    iterator __first1 = begin();
    iterator __last1 = end();
    iterator __first2 = __x.begin();
    iterator __last2 = __x.end();
    whlie(*__first1 != *__last1 && *__first2 != *__last2){
        if (*__first2 < *__first1){
            iterator __next == __first2;

            // GeorgeCaoJ's improvement opinion
            while(*(++next) < *first1){};
            // GeorgeCaoJ's improvement opinion
            
            transfer(__first1, __first2, ++next);
            __first2 = __next;
        }
        else
            ++__first1;
        if (__first2 != __last2)
            transfer(__last1, __first2, __last2);
    }
}

deque

stack & queue

heap

priority queue

关联式容器

set、multiset、map、multimap底层实现--红黑树RB-tree

set

map

template <class T1, class T2>
struct pair{
    typedef T1 first_type;
    typedef T2 second_type;
    T1 first;
    T2 second;
    pair():first(T1()), second(T2()){}
    pair(const T1& a, const T2& b):first(a), second(b){}
};

multiset & multimap

hash_set、hash_multiset、hash_map、hash_multimap底层实现——hashtable

hash_set、hash_multiset、hash_map、hash_multimap

算法

迭代器

迭代器将元素的遍历动作进行抽象和统一接口:对于具有连续空间类型的容器,迭代器--和++动作对应了指针的--和++;而对应于非连续空间的容器,如list链表,迭代器--和++对应与链表的指针移动。因此,迭代器也属于泛化的一部分,为算法泛化提供了便利。

Sort算法

作为最基本的常用的基础算法,STL追求速度和性能上的优化,对sort算法也是有很多优化细节。

堆排比较的几乎都不是相邻元素,对cache极不友好。数学上的时间复杂度不代表实际运行时的情况

涉及计算机存储器结构,CPU每次都是对缓存成块进行读取,所以不相邻的元素会频繁在缓存中切换访问的块,所以一个优秀的代码需要考虑缓存友好,考虑到缓存局部性的特点。