[STL] Implement "vector", ”deque“ and "list"
vector
“可增的”数组
vector是一块连续分配的内存,从数据安排的角度来讲,和数组极其相似。
不同的地方就是:
(1) 数组是静态分配空间,一旦分配了空间的大小,就不可再改变了;
(2) vector是动态分配空间,随着元素的不断插入,它会按照自身的一套机制不断扩充自身的容量。
内存模型
vector发现自己的空间不够了,于是申请新的内存空间(自增一倍),并将前面已有数据复制到新空间的前部。
Comment
自增一倍,主要是“位移”运算。
对于vector增加新元素的时候,有可能很快完成,也有可能要进行扩容,效率下降;
删除末尾元素效率很高,删除中间元素效率低;
deque
双端队列
deque是双端队列,在接口上和vector非常相似,在许多操作的地方可以直接替换。
与vector不同的是,deque不能保证所有的元素存储在连续的空间中,在deque中通过指针加偏移量方式访问元素可能会导致非法的操作。
内存模型
Ref: C++ STL学习之三:容器deque深入学习(转)
除了在频繁在头部或尾部进行插入和删除操作外,deque比list和forward_list的性能更差。
deque是一种优化了的对序列两端元素进行添加和删除操作的基本序列容器。
通常由一些独立的区块组成,第一区块朝某方向扩展,最后一个区块朝另一方向扩展。
它允许较为快速地随机访问但它不像vector一样把所有对象保存在一个连续的内存块,而是多个连续的内存块。并且在一个映射结构中保存对这些块以及顺序的跟踪。

Ref: STL源码剖析---deque
deque采用一块所谓的map(注意,不是STL的map容器)作为主控。这里所谓map是一小块连续空间,其中每个元素(此处称为一个节点,node)都是指针,指向另一段(较大的)连续线性空间,称为缓冲区。缓冲区才是deque的储存空间主体。
SGI STL 允许我们指定缓冲区大小,默认值0表示将使用512 bytes 缓冲区。
deque的迭代器
让我们思考一下,deque的迭代器应该具备什么结构,首先,
- 它必须能够指出分段连续空间(亦即缓冲区)在哪里;
- 其次它必须能够判断自己是否已经处于其所在缓冲区的边缘,如果是,一旦前进或后退就必须跳跃至下一个或上一个缓冲区。
为了能够正确跳跃,deque必须随时掌握管控中心(map)。所以在迭代器中需要定义:当前元素的指针,当前元素所在缓冲区的起始指针,当前元素所在缓冲区的尾指针,指向map中指向所在缓区地址的指针。
List
内核链表
From: 深入分析 Linux 内核链表
struct list_head {
struct list_head *next, *prev;
};
#define list_entry(ptr, type, member) container_of(ptr, type, member)
// container_of宏定义在[include/linux/kernel.h]中
#define container_of(ptr, type, member) ({ \
const typeof( ((type *))->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
// offsetof宏定义在[include/linux/stddef.h]中
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
内存模型
也就是普通的方式.
template <class T>
struct __list_node {
typedef void* void_pointer;
void_pointer prev;
void_pointer next;
T data;
};
Understand the cons and pros

数组 & 单链表
std::array
std::array is just a class version of the classic C array. That means its size is fixed at compile time and it will be allocated as a single chunk (e.g. taking space on the stack). The advantage it has is slightly better performance because there is no indirection between the object and the arrayed data.
std::forward_list
"又快又小,但要在逻辑层面上:结构和需求相吻合."
forward_list 容器以单链表的形式存储元素。forward_list 的模板定义在头文件 forward_list 中。fdrward_list 和 list 最主要的区别是:它不能反向遍历元素;只能从头到尾遍历。
forward_list 的单向链接性也意味着它会有一些其他的特性:
- 无法使用反向迭代器。只能从它得到const或non-const前向迭代器,这些迭代器都不能解引用,只能自增;
- 没有可以返回最后一个元素引用的成员函数back();只有成员函数front();
- 因为只能通过自增前面元素的迭代器来到达序列的终点,所以push_back()、pop_back()、emplace_back()也无法使用。
forward_list 的操作比 list 容器还要快,而且占用的内存更少,尽管它在使用上有很多限制,但仅这一点也足以让我们满意了。
End.
[STL] Implement "vector", ”deque“ and "list"的更多相关文章
- STL之vector,deque学习实例
``` #include<iostream> #include<algorithm> #include<ctime> #include<vector> ...
- stl 中List vector deque区别
stl提供了三个最基本的容器:vector,list,deque. vector和built-in数组类似,它拥有一段连续的内存空间,并且起始地址不变,因此 它能非常好的支持随 ...
- STL中vector、list、deque和map的区别
1 vector 向量 相当于一个数组 在内存中分配一块连续的内存空间进行存储.支持不指定vector大小的存储.STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即capac ...
- 【转】STL中vector、list、deque和map的区别
1.vector 向量 相当于一个数组 在内存中分配一块连续的内容空间进行存储.支持不指定vector大小的存储.STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即capacity()函数 ...
- C++的STL中vector内存分配方法的简单探索
STL中vector什么时候会自动分配内存,又是怎么分配的呢? 环境:Linux CentOS 5.2 1.代码 #include <vector> #include <stdio ...
- 顺序容器:vector,deque,list
1.顺序容器:vector,deque,list 容器类共享公共接口,只要学会其中一种类型就能运用另一种类型.每种容器提供一组不同的时间和功能这种方案,通常不需要修改代码,秩序改变类型声明,每一种容器 ...
- 带你深入理解STL之Vector容器
C++内置了数组的类型,在使用数组的时候,必须指定数组的长度,一旦配置了就不能改变了,通常我们的做法是:尽量配置一个大的空间,以免不够用,这样做的缺点是比较浪费空间,预估空间不当会引起很多不便. ST ...
- C++STL之Vector向量详解,用法和例子 一起学习 一起加油
C++ STL之vector用法总结 1 ...
- vector deque list
vector ,deque 和 list 顺序性容器: 向量 vector : 是一个线性顺序结构.相当于数组,但其大小可以不预先指定,并且自动扩展.它可以像数组一样被操作,由于它的特性我们完全可 ...
随机推荐
- SpringCould-------使用Hystrix 实现断路器进行服务容错保护
消费: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.or ...
- idea使用springboot的webservice基于cxf
SpringBoot整合CXF实例: 服务端构建 <dependency> <groupId>org.apache.cxf</groupId> <artifa ...
- Oracle 12c Adoption Discussion — Summary
Morning (@9:30) Oracle 12c Overview & Features for Developers Oracle Database In-Memory Deep Div ...
- C# - 协变、逆变 看完这篇就懂了
1. 基本概念 官方:协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型.[MSDN] 公式: ...
- ionic3.x脚手架(基于个人项目自用)
ionic3项目开发脚手架(基于个人练习项目) 一. 基于ionic3的生产环境搭建 1. 配置安卓SDK: 安装jdk ---> 安装AndroidSDK (1) 安 ...
- Python机器学习笔记:不得不了解的机器学习知识点(2)
之前一篇笔记: Python机器学习笔记:不得不了解的机器学习知识点(1) 1,什么样的资料集不适合用深度学习? 数据集太小,数据样本不足时,深度学习相对其它机器学习算法,没有明显优势. 数据集没有局 ...
- ES6之模块化导入导出
1.概述 在js的历史上一直没有模块(module)体系,无法将一个大程序拆分成相互依赖的小文件,再用简单的方法拼装起来,这对开发大型的.复杂的项目形成了巨大障碍. 在 ES6 之前,社区制定了一些模 ...
- CentOS 7 下 JDK1.8+Maven+Nginx+MySql+Git+Redis环境安装
CentOS 7 下 JDK1.8+Maven+Nginx+MySql+Git+Redis环境安装 安装目录准备 新建data目录,用来放下载的软件 mkdir -p /data 切换到该data目录 ...
- Commons组件实现文件上传与下载
一.文件上传 所需jar包 首先是commons-fileupload.jar包 其次是commons-IO.jar包 前者的使用依赖后者,两者缺一不可 实现 前台要求 在前台提交的form表单请求方 ...
- NLP(十九) 双向LSTM情感分类模型
使用IMDB情绪数据来比较CNN和RNN两种方法,预处理与上节相同 from __future__ import print_function import numpy as np import pa ...