最近由于找工作需要,准备深入学习一下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. 使用VSCode和VS2017编译调试STM32程序

    近两年,微软越来越拥抱开源支持跨平台,win10搭载Linux子系统,开源VSCode作为跨平台编辑器,VS2017官方支持了Linux和嵌入式开发功能. ST也是,近两年开发的软件工具基本都是跨平台 ...

  2. Oracle多行记录合并的几种方法

    今天正好遇到需要做这个功能,顺手搜了一下网络,把几种方法都列出来,方便以后参考. 1 什么是合并多行字符串(连接字符串)呢,例如: SQL> desc test; Name Type Nulla ...

  3. j2e中操作EXCEL

    在j2e中操作excel,无非2种情况,在这里我贴部分代码做个例子就OK,不管是导入和导出都是操作的都是流 1,导入,浏览器输入EXCEL到java后台解析 package action; impor ...

  4. linkin大话数据结构--List

    List:Collection子接口 List是有序的集合,集合中每个元素都有对应的顺序序列.List集合可使用重复元素,可以通过索引来访问指定位置的集合元素(顺序索引从0开始),List集合默认按元 ...

  5. mavean的依赖传递和排除依赖

    三个mavean项目 A  .B. C 如果B依赖A(A先执行clean package命令) 那么B得pom.xml文件里面就写 <dependency> <groupId> ...

  6. 优秀的基于VUE移动端UI框架合集

    1. vonic 一个基于 vue.js 和 ionic 样式的 UI 框架,用于快速构建移动端单页应用,很简约,是我喜欢的风格 star 2.3k 中文文档 在线预览 2.vux 基于WeUI和Vu ...

  7. Linux下passwd和shadow文件内容详解

    一./etc/passwd /etc/passwd 文件是一个纯文本文件,每行采用了相同的格式: name:password:uid:gid:comment:home:shell name 用户登录名 ...

  8. 5分钟编写运行一个RChain合约

    今天介绍如何编写和测试一个RChain智能合约,Rholang的语法介绍在https://developer.rchain.coop/tutorial 1.安装docker 这个自己百度一下,安装都是 ...

  9. Tomcat就是这么简单

    什么是Tomcat Tomcat简单的说就是一个运行JAVA的网络服务器,底层是Socket的一个程序,它也是JSP和Serlvet的一个容器. 为什么我们需要用到Tomcat 如果你学过html,c ...

  10. 解决在Ubuntu系统下用matplotlib作图时出现中文乱码问题

    今天在jupyter notebook中画图时,中文不能正常显示,如下图所示: 在此记录一下解决的办法. 1.找到matplotlib配置文件的位置 import matplotlib print(m ...