1. STL的空间配置器

  SGI STL设计了双层级配置器,第一级配置器直接使用malloc()、free(),第二级配置器则视情况采用不同的策略:当配置区块超过128bytes时,视为“足够大”,便调用第一级配置器;当配置区块小于128bytes时,视为“过小”,为降低额外负担,便采用复杂的memory pool整理方式,不再求助于第一级配置器。第二级配置器维护16个自由链表,负责16种小型区块的次配置能力。内存池以malloc()配置而得。如果内存不足,转调用第一级配置器。

  设计“内存不足处理例程”是客户端的责任。如果客户端没有设计,则STL直接丢出bad_alloc异常,或利用exit(1)直接退出程序。

  当第二级配置器配置区块时,会将要配置的小额区块的内存需求量上调至8的倍数。当发现自由链表(free list)中没有可用区块时,就调用refill(),缺省取得20个新节点。

2. STL的迭代器

  迭代器(iterator):扮演容器与算法之间的胶合剂,是所谓的“泛型指针”,迭代器必须实现operator*, operator->, operator++, operator--。因为只有容器设计者知道该如何遍历自己的元素,所以STL并没有将迭代器单独列出来以满足所有的容器。

  偏特化(Partial Specialization),意思是如果class template拥有一个以上的template参数,可以针对其中某个(或数个,但非全部)template参数进行特化工作。(另一种解释是针对任何template参数更进一步的条件限制所设计出来的一个特化版本)。

  Quick Sort的泛型算法一定要求迭代器是RandomAccessIterators。因为任何一个元素都可以被选作枢轴(pivot),但是其合适与否却会影响Quick Sort的效率。为了避免枢轴不够随机带来的恶化效应,最理想的方式是取整个序列的头、尾、中央三个位置的元素,以其中值作为枢轴,这种做法成为三点中值(Median-of-Three),为了能够快速取出中央位置的元素,显然迭代器必须能够随机定位,因此快速排序的泛型算法中迭代器必须是RandomAccessIterators。

3. 序列式容器

  vector维护的是一个连续线性空间(可以理解为数组),支持随机存取,因此提供的迭代器是RandomAccessIterators。增加新元素时,如果超过当时的容量,则容量会扩充至两倍。所谓的动态增加大小,并不是在原空间之后接续新空间,而是以原大小的两倍另外配置一块空间,然后将原内容拷贝过来,然后才开始在原内容之后构造新元素,并释放原空间。因此,对vector的任何操作,一旦引起空间重新配置,指向原vector的所有迭代器就都失效了。

  list封装了链表。SGI STL的list是一个双向链表(double linked-list),迭代器必须具备前移和后移的能力,所以list提供的是Bidirectional Iterator(注意,list不支持随机存取,所以提供的不是RandomAccessIterators)。list的删除操作只有“指向被删除元素”的那个迭代器失效,其他迭代器不受影响。

  list和vector的最主要的区别在于vector使用连续内存存储的,它支持[]运算符,而list是以链表形式实现的,不支持[]。vector对于随机访问的速度很快,但是对于插入尤其是在头部插入元素速度很慢,在尾部插入速度很快。list对于随机访问速度慢得多,因为可能要遍历整个链表才能做到,但是对于插入就快的多了,不需要拷贝和移动数据,只需要改变指针的指向就可以了。另外对于新添加的元素,vector有一套算法,而list可以任意加入。

  vector是单向开口的连续线性空间,deque则是一种双向开口的连续线性空间。vector当空间不足时,是另外分配一块空间,拷贝原有内容,删除旧空间;而deque是另外分配一块空间,但是deque的接口提供的还是连续的接口,显然deque内部的迭代器做了很多工作,使得deque至少看起来是连续线性的。

  stack是封装的deque,换句话说stack实际上是一种配接器。配接器是对内部物的某些接口的封装,不提供内部物的其他接口的访问,与继承等有明显不同。

4. 关联式容器

 map,set属于标准关联容器,使用了非常高效的平衡搜索二叉树:红黑树(RB-tree),它的插入删除效率比其他序列容器高是因为不需要做内存拷贝和内存移动,而直接替换指向节点的指针即可。平衡二叉树有许多种类型,包括AVL-tree、RB-tree等。

  二叉搜索树(binary search tree),又称二叉查找树,二叉排序树,可提供对数时间的元素插入和访问。二叉搜索树的节点放置规则是:任何节点的键值一定大于其左子树中每一个节点的键值,并小于其右子树中的每一个节点的键值。因此,从根节点一直往左走,直至无左路可走,即得最小元素;相反,即得最大元素。

  注意,二叉搜索树的插入和删除常作为面试题。删除操作分为两种情况,一种是被删除节点只有一个子节点,直接将该子节点替换被删除节点的父节点即可;第二种是被删除节点的左右子节点都在,则将右子树中的最小值替换被删除节点即可。

  set自动排序,不能直接修改元素,需要先删除再插入,不能重复,multiset可以。set插入删除元素后,原有的除了被删除节点迭代器的其他迭代器不失效。set之所以不能直接修改元素值,是因为set的元素值就是其键值,关系到set元素的自动排序规则。

  map会根据元素的键值自动排序。map的所有元素都是pair,同时拥有键值(key)和实值(value)。pair的第一元素称为键值,第二个元素称为实值。map的键值不允许修改。map不允许两个元素拥有相同的键值。

  set和vector的区别在于set不包含重复的数据。set和map的区别在于set只含有key,而map有一个key和key所对应的value两个元素。map和hash_map的区别是hash_map使用了hash算法来加快查找过程,但是需要更多的内存来存放这些hash元素,因此可以算得上是采用空间来换取时间策略。

《STL源码剖析》要点摘抄的更多相关文章

  1. STL"源码"剖析-重点知识总结

    STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合 ...

  2. 【转载】STL"源码"剖析-重点知识总结

    原文:STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点 ...

  3. (原创滴~)STL源码剖析读书总结1——GP和内存管理

    读完侯捷先生的<STL源码剖析>,感觉真如他本人所说的"庖丁解牛,恢恢乎游刃有余",STL底层的实现一览无余,给人一种自己的C++水平又提升了一个level的幻觉,呵呵 ...

  4. 《STL源码剖析》环境配置

    首先,去侯捷网站下载相关文档:http://jjhou.boolan.com/jjwbooks-tass.htm. 这本书采用的是Cygnus C++ 2.91 for windows.下载地址:ht ...

  5. STL源码剖析读书笔记之vector

    STL源码剖析读书笔记之vector 1.vector概述 vector是一种序列式容器,我的理解是vector就像数组.但是数组有一个很大的问题就是当我们分配 一个一定大小的数组的时候,起初也许我们 ...

  6. STL源码剖析 迭代器(iterator)概念与编程技法(三)

    1 STL迭代器原理 1.1  迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型,STL设计的精髓在于,把容器(Containers)和算法(Algorithms)分开,而迭代器(i ...

  7. STL"源码"剖析

    STL"源码"剖析-重点知识总结   STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略 ...

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

    原文链接:http://www.cnblogs.com/raichen/p/5817158.html 一.STL简介 STL提供六大组件,彼此可以组合套用: 容器容器就是各种数据结构,我就不多说,看看 ...

  9. STL源码剖析之序列式容器

    最近由于找工作需要,准备深入学习一下STL源码,我看的是侯捷所著的<STL源码剖析>.之所以看这本书主要是由于我过去曾经接触过一些台湾人,我一直觉得台湾人非常不错(这里不涉及任何政治,仅限 ...

  10. STL源码剖析 — 空间配置器(allocator)

    前言 以STL的实现角度而言,第一个需要介绍的就是空间配置器,因为整个STL的操作对象都存放在容器之中. 你完全可以实现一个直接向硬件存取空间的allocator. 下面介绍的是SGI STL提供的配 ...

随机推荐

  1. Excel Metadata

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  2. Bzoj3277:串

    题面 传送门 Sol 广义\(sam\) 每个\(sam\)的状态开\(set\)记录属于哪些串 \(parent\)树上启发式合并\(set\) 然后每个串就在上面走,通过不停地跳\(parent\ ...

  3. SVN - Checksum mismatch while updating

    Go to the folder with the file causing problems Execute command svn update --set-depth empty (note: ...

  4. Django最佳实践(中文版)

    这是一份关于开发和部署 Django Web 框架 的动态文档 (会随时更新). 这些准则不应该被认为是 绝对正确 或 唯一 使用 Django 的方法, 应该说这些最佳实践是我们使用框架多年来积累的 ...

  5. arcgis for js/flex/sl 该选哪一个?

    arcgis server开发webgis 在客户端有3种选择:js.flex.sl 他们除了开发arcgis外,本身还有一些常用的领域 js:在传统网站中很常用 flex:游戏.视频播放.动画特效 ...

  6. 使用 grep 的 -o 和 -E 选项进行正则的精确匹配

    sed 命令可以很好的进行行匹配,但从某一行中精确匹配某些内容,则使用 grep 命令并辅以 -o 和 -E 选项可达到此目的.其中 -o 表示“only-matching”,即“仅匹配”之意.光用它 ...

  7. C# 冒泡排序法、插入排序法、选择排序法

    冒泡排序法 是数组等线性排列的数字从大到小或从小到大排序. 以从小到大排序为例. 数据 11, 35, 39, 30, 7, 36, 22, 13, 1, 38, 26, 18, 12, 5, 45, ...

  8. 枚举类型与位域枚举Enum

    一.概述 定义一个值类型,其中包含固定值集合.枚举类型变量可以是此集合中的任意一个或多个值.枚举使用enum关键字来声明,与类同级.枚举本身可以有修饰符,但枚举的成员始终是公共的,不能有访问修饰符.枚 ...

  9. codeforces 633E Startup Funding(浮点数处理)

    codeforces 633E Startup Funding 题意 枚举左端点,对于每个左端点求一个最大的右端点使得最大. 对于得到的这个数组,随机选择k个数,求最小值期望. 题解 对于每个左端点, ...

  10. codeforces 388D Fox and Perfect Sets(线性基+数位dp)

    #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define mp mak ...