STL源码剖析之序列式容器
最近由于找工作需要,准备深入学习一下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源码剖析之序列式容器的更多相关文章
- STL源码剖析:序列式容器
前言 容器,置物之所也.就是存放数据的地方. array(数组).list(串行).tree(树).stack(堆栈).queue(队列).hash table(杂凑表).set(集合).map(映像 ...
- STL源码剖析:关联式容器
AVL树 AVL树定义:红黑树是一颗二叉搜索树,特别的是一棵保持高度平衡的二叉搜索树 AVL树特点: 每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1 AVL树插入: 说明:新增节点的平衡因子 ...
- c++ stl源码剖析学习笔记(三)容器 vector
stl中容器有很多种 最简单的应该算是vector 一个空间连续的数组 他的构造函数有多个 以其中 template<typename T> vector(size_type n,cons ...
- STL源码剖析——序列式容器#1 Vector
在学完了Allocator.Iterator和Traits编程之后,我们终于可以进入STL的容器内部一探究竟了.STL的容器分为序列式容器和关联式容器,何为序列式容器呢?就是容器内的元素是可序的,但未 ...
- STL"源码"剖析-重点知识总结
STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合 ...
- 【转载】STL"源码"剖析-重点知识总结
原文:STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点 ...
- STL源码剖析读书笔记之vector
STL源码剖析读书笔记之vector 1.vector概述 vector是一种序列式容器,我的理解是vector就像数组.但是数组有一个很大的问题就是当我们分配 一个一定大小的数组的时候,起初也许我们 ...
- STL"源码"剖析
STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略 ...
- STL源码剖析 迭代器(iterator)概念与编程技法(三)
1 STL迭代器原理 1.1 迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型,STL设计的精髓在于,把容器(Containers)和算法(Algorithms)分开,而迭代器(i ...
随机推荐
- 企业级分布式存储应用与实战-mogilefs实现
Mogilefs是什么 MogileFS是一个开源的分布式文件存储系统,由LiveJournal旗下的Danga Interactive公司开发.Danga团队开发了包括 Memcached.Mogi ...
- Django 中 makemigrations、migrate时 No changes detected
Django创建的项目中,需要更改.增加.删除表中的某些属性,性急直接把之前数据库表删除了,之后再执行: python manage.py makemigrations python manage.p ...
- CentOS7 配置花生壳开机启动
在家安装服务器,外地可以随时登陆,感觉花生壳特别方便,具体路由器配置请参考http://service.oray.com/question/2486.html. 我使用的操作系统是 [root@loc ...
- struts2 利用通配符方式解决action太多的问题
<!-- 创建包default,继承struts-default --> <package name="default" extends="str ...
- 验证码 jsp
验证码的jsp实现 <%@ page contentType="image/jpeg" import="java.awt.*, java.awt.image.*,j ...
- PHP面试题超强总结(PHP中文网)
PHP面试基础题目 1.双引号和单引号的区别 双引号解释变量,单引号不解释变量 双引号里插入单引号,其中单引号里如果有变量的话,变量解释 双引号的变量名后面必须要有一个非数字.字母.下划线的特殊字符, ...
- Javascript的异步和回调
介绍JavaScript的一些同步.异步.单线程多线程,回调基本概念:https://segmentfault.com/a/1190000002999668
- 13 Basic Cat Command Examples in Linux(转) Linux中cat命令的13中基本用法
Cat (串联) 命令是Linux/Unix开源系统中比较常用的一个命令.我们可以通过Cat命令创建一个或多个文件,查看文件内容,串联文件并将内容输出到终端设备或新的文件当中,这篇文章我们将会以实例的 ...
- [DeeplearningAI笔记]02_3.1-3.2超参数搜索技巧与对数标尺
Hyperparameter search 超参数搜索 觉得有用的话,欢迎一起讨论相互学习~Follow Me 3.1 调试处理 需要调节的参数 级别一:\(\alpha\)学习率是最重要的需要调节的 ...
- 浅谈对SpringMVC的认识
SpringMVC概念: 他是一个轻量级的开源框架,应用于表现层,基于MVC的设计模式. SpringMVC的特点: 1.他是单例的可以设置成多例. 2.他的线程是安全的 ...