最近由于找工作需要,准备深入学习一下STL源码,我看的是侯捷所著的《STL源码剖析》。之所以看这本书主要是由于我过去曾经接触过一些台湾人,我一直觉得台湾人非常不错(这里不涉及任何政治,仅限个人感受),在技术上他们比较严谨,在为人处世上也非常谦虚,所以一些台湾的技术资料我觉得是值得一看的。

想要学习STL源码的设计,其实应该是从空间适配器(allocator)和迭代器(iterators)开始看起的,但是我没有对这两个部分做深入研究,主要原因是最近实在太忙,要写论文又要兼顾找工作,不能在这上面投入太大精力,而这两个部分又不太容易看懂,所以我决定先从容器开始看起,这样在编码时用到c++标准库的时候会更有底气。

关于容器的设计,其实我们在算法与数据结构课程里都涉及过,但是当时主要集中于理解设计理念,没有真正编过一套完整的库去应用我们学习到的知识,所以读者在学习c++标准库的时候我觉得应该结合过去数据结构的知识,关注它实现的技巧和为什么这么实现,通过学习优秀代码提升自己的编程能力。

容器分为序列式容器与关联式容器,本篇博客主要讨论序列式容器,所谓序列式容器,其中的元素都可序(ordered),但是未必有序(sorted)。C++本身提供了一个序列式容器array,STL另外再提供vector、list、deque,再以此为基础实现heap(内含vector),stack和queue(内含deque),后面会展开叙述,其实这里的stack和queue只是将deque改头换面而形成的,技术上被归类为一种配接器(adapter)。

由于篇幅,本文还是从使用者的角度介绍各个接口的设计思路。

Vector

Vector的迭代器

vector维护的是一个连续线性的空间,所以它的迭代器很好实现,只需要一个普通指针就可以(和元素类型无关),迭代器所需要的操作行为包括:operator*,operator->,operator++,operator--,operator+,operator-,operator+=,operator-=,普通指针天生就具备。,vector支持随机存取,它提供的是Random Access Iterators,普通指针也有这样的能力。所以,如果客户端写出这样的代码:

vector<int>::iterator ivite;

那么ivite的类型就是int *。

vector的构造与内存管理

vector里面有三个迭代器,start、finish、end_of_storage,分别指向当前连续空间所使用的头和尾、整块连续空间的尾。为了降低空间配置时的速度成本,vector实际配置的大小要比客户端需求量更大一些,以备将来的使用。vector空间的增长实际上是一个浩大的工程,开销非常大,它需要申请一块新的连续空间,然后把已有的内容拷贝过去,这里面每次新扩充的空间都是原空间的两倍大,这样做可以把扩充空间的时间复杂度降低到O(n),如果每次新扩充的空间相比于原空间增加一个固定的大小m,那么无论m取何值,都可以证明最后的时间复杂度正比于n的平方。

vector元素操作:push_back,pop_back,erase,clear,insert

void push_back(const T& x) //将元素插入于vector的尾端,该函数首先检查是否还有备用空间,如果有就直接在备用空间上构造元素,调整迭代器finish,如果没有备用空间,就
//扩充空间(重新配置、移动数据、释放原空间)
void pop_back() //将尾端元素删除。
iterator erase(iterator first,iterator last) //删除[first,last)中的所有元素
iterator erase(iterator position) //清除某个位置上的元素
void clear() //清除所有元素
void insert(iterator postion,size_type n,const T& x) //从position开始,插入n个元素,元素初值为x

list

list和vector是两个最常用的容器,list的特点是:每次插入或删除一个元素,就配置或释放一个元素空间。list对于空间的运用有绝对的精准,而且对于任意位置的元素插入或删除的时间复杂度是O(1),但是list不支持随机访问,它只能从头开始遍历元素,这点不如vector,因此它们的使用需要根据具体的情况具体分析。

list的迭代器

list不像vector一样可以用普通指针作为迭代器,因为其结点不保证在存储空间中连续存在。list迭代器需要能够指向list的节点,并且可以进行正确的递增、递减、取值操作、成员取用操作,其实都很简单,这里不列代码了。

STL源码剖析之序列式容器的更多相关文章

  1. STL源码剖析:序列式容器

    前言 容器,置物之所也.就是存放数据的地方. array(数组).list(串行).tree(树).stack(堆栈).queue(队列).hash table(杂凑表).set(集合).map(映像 ...

  2. STL源码剖析:关联式容器

    AVL树 AVL树定义:红黑树是一颗二叉搜索树,特别的是一棵保持高度平衡的二叉搜索树 AVL树特点: 每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1 AVL树插入: 说明:新增节点的平衡因子 ...

  3. c++ stl源码剖析学习笔记(三)容器 vector

    stl中容器有很多种 最简单的应该算是vector 一个空间连续的数组 他的构造函数有多个 以其中 template<typename T> vector(size_type n,cons ...

  4. STL源码剖析——序列式容器#1 Vector

    在学完了Allocator.Iterator和Traits编程之后,我们终于可以进入STL的容器内部一探究竟了.STL的容器分为序列式容器和关联式容器,何为序列式容器呢?就是容器内的元素是可序的,但未 ...

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

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

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

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

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

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

  8. STL"源码"剖析

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

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

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

随机推荐

  1. Pandas(python)数据处理:只对某一列DataFrame数据进行归一化

    处理数据要用到Pandas,但是没有学过,不知道是否有直接对某一列归一化的方法调用.自己倒弄了下.感觉还是比较麻烦. 使用Pandas读取到数组之后想把其中的'MonthlyIncome'一列进行归一 ...

  2. linux 中nvme 的中断申请及处理

    /** * struct irq_desc - interrupt descriptor * @irq_data: per irq and chip data passed down to chip ...

  3. Java高级工程师——面试总结

    面试技巧 1.背熟你的简历 原因:面试的第一个问题,一般都是让你简单介绍下你自己,或者介绍一下你最近的项目,而一个面试者,如果连自己的简历都无法熟知,对里面提到的项目.技术都无法描述清楚的话,我想没有 ...

  4. Python程序的执行方式

    Python代码有两种执行方式: 一.文件执行 二.交互器执行(推荐) 一.文件执行 1.用 notepad++ 或 Sublime Text,甚至 写字本创建一个文件. 2.比如:print('He ...

  5. java面向对象基础(四):抽象类和接口

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  6. PHP读取XML文件

    xml主键被json取代,大概了解一下就OK了 简要: 加载xml文件:$xml = simplexml_load_file('sa.xml');//$xml是一个对象 读取节点:echo $xml- ...

  7. hdu3507 Print Article

    Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) P ...

  8. 面试中的Java链表

    链表作为常考的面试题,并且本身比较灵活,对指针的应用较多.本文对常见的链表面试题Java实现做了整理. 链表节点定义如下: static class Node { int num; Node next ...

  9. Prime - 程序员的修养

    求质数算法的N种境界 求质数算法的N种境界[1] - 试除法和初级筛法 过程 尽管题目并没有要我们写一个最优的算法,但是身为一个程序员,优化应该是一种习惯,在编程的过程中,随着思考进行优化. 如果你只 ...

  10. OSSEC初探

    OSSEC初探 概念: OSSEC是一款开源的基于主机的入侵检测系统(HIDS),它可以执行日志分析.完整性检验.windows注册表监控.隐匿性检测和实时告警.它可以运行在各种不同的操作系统上,包括 ...