Array,Vector,List,Deque的区别与联系【转+改】
数组
内存连续分配,长度大小固定,内置的最基础的数据结构之一。支持随机访问和随机存储。
该类型数据所占内存空间最小。
Vector
是C++ STL中的一个容器。和数组类似,它拥有一段连续的内存空间,并且起始地址不变,因此它能非常好的支持随机存取(即使用[]操作符访问其中的元素),但由于它的内存空间是连续的,所以在中间进行插入和删除会造成内存块的拷贝(复杂度是O(n)),另外,当该数组后的内存空间不够时,需要重新申请一块足够大的内存并进行内存的拷贝。这些都大大影响了vector的效率。
Vector的原型定义如下。可以看到,作为一个容器,相比array附加了很多数据成员,因而从整体上而言,其内存空间占用较数组更多。但是仅仅就分配的连续的数组空间而言,和内置型数组占用空间大小基本一致。
// vector 基类 _Vector_base 定义
template <class _Tp, class _Alloc>
class _Vector_base {
public:
typedef _Alloc allocator_type;
// 获取一个空间配置器对象
allocator_type get_allocator() const { return allocator_type(); }
// 默认构造:没有指定初始节点个数
_Vector_base(const _Alloc&)
: _M_start(), _M_finish(), _M_end_of_storage() {}
// 构造函数:指定节点个数n
_Vector_base(size_t __n, const _Alloc&)
: _M_start(), _M_finish(), _M_end_of_storage()
{
// 分配 n 个节点所需空间
_M_start = _M_allocate(__n); // _M_start 指向起始位置
_M_finish = _M_start; // _M_finish 指向其实位置
_M_end_of_storage = _M_start + __n; // _M_end_of_storage指向内存末尾节点
}
// 析构函数:释放内存空间
~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); } protected:
_Tp* _M_start; // 指向第一个元素所在的节点
_Tp* _M_finish; // 指向最后一个元素所在节点的下一个节点
_Tp* _M_end_of_storage; // 可用内存空间的末尾节点
// 空间配置器
typedef simple_alloc<_Tp, _Alloc> _M_data_allocator;
// 分配 n 个节点所需要的空间
_Tp* _M_allocate(size_t __n)
{ return _M_data_allocator::allocate(__n); }
// 释放 n 个节点所对应的空间
void _M_deallocate(_Tp* __p, size_t __n)
{ _M_data_allocator::deallocate(__p, __n); }
};
List
list是由数据结构中的双向链表实现的,因此它的内存空间可以是不连续的。因此只能通过指针来进行数据的访问,这个特点使得它的随机存取变的非常没有效率,需要遍历中间的元素,搜索复杂度O(n),因此它没有提供[]操作符的重载。但由于链表的特点,它可以以很好的效率支持任意地方的删除和插入。
其定义如下所示,很明显,除了数据域以外,还包含前向指针后后序指针,因而其耗费的空间比vector要大。
// ListNodeBase定义
struct _List_node_base {
_List_node_base* _M_next;
_List_node_base* _M_prev;
}; // ListNode定义
template <class _Tp>
struct _List_node : public _List_node_base {
_Tp _M_data; // 数据域
};
Deque
deque是双端队列,在队列头部和尾部可以快速的进行元素的插入和删除操作,相比vector而言有一定的优势,同时由于内部构造的设计,不存在vector那样扩充时带来的“配置新空间 / 移动旧数据 / 释放旧空间”问题。deque还提供Random Access Iterator,可以随机访问容器内的元素。deque同时还是STL中queue和stack的底层依赖组件。
下面的图片展示deque的内部结构设计。可以看到,deque拥有一个bitmap结构(称之为map),map中每一个元素指向一块连续的内存块,后者才是真正存储deque元素的地方,因为每个块都是固定大小的,但是每个块之间不要求是连续的,所以扩充空间的时候,就没有vector那样的副作用了。
deque的数据结构更为复杂,还包含了map节点,但是相比list每个节点均需要额外指针而言,其内存占用量还是较少。所以deque数据部分消耗的内存空间大小应该在vector和list之间。
需要说明的是,stack和queue的内部实现均基于deque实现,queue只能头删尾进,stack只能尾删尾进,这都是deque所支持的操作的特殊情况,或者说一个子集。
Array,Vector,List,Deque的区别与联系【转+改】的更多相关文章
- vector与deque的区别
最重要的区别,是内部实现上.deque是分段存储的. 都是支持随机存取. http://www.cnblogs.com/zhuyf87/archive/2012/12/09/2809896.html ...
- C++ vector,list,deque区别(转)
在写C++程序的时候会发现STL是一个不错的东西,减少了代码量,使代码的复用率大大提高,减轻了程序猿的负担.还有一个就是容器,你会发现要是自己写一个链表.队列,或者是数组的时候,既要花时间还要操心 ...
- C++ vector、list和deque的区别 (整理)
1.vector数据结构 vector和数组类似,拥有一段连续的内存空间,并且起始地址不变.因此能高效的进行随机存取,时间复杂度为o(1);但因为内存空间是连续的,所以在进行插入和删除操作时,会造成内 ...
- 【转】java 容器类使用 Collection,Map,HashMap,hashTable,TreeMap,List,Vector,ArrayList的区别
原文网址:http://www.360doc.com/content/15/0427/22/1709014_466468021.shtml java 容器类使用 Collection,Map,Hash ...
- 一道java笔试题目:Vector和ArrayList的区别
Vector和ArrayList的区别 线性表,链表,哈希表是常用的数据结构,在进行Java开发时,JDK已经为我们提供了一系列相应的类来实现基本的数据结构这些类均在java.util包中本文试图通过 ...
- C++进阶 STL(1) 第一天 [容器,算法,迭代器] string容器 vector容器 deque容器
课程大纲 02实现基本原理 容器,算法,迭代器 教室:容器 人:元素 教室对于楼:容器 序列式容器: 容器元素在容器中的位置是由进入容器的时间和地点来决定 序列式容器 关联式容器: 教室中 按年龄排座 ...
- OpenGL中glVertex、显示列表(glCallList)、顶点数组(Vertex array)、VBO及VAO区别
OpenGL中glVertex.显示列表(glCallList).顶点数组(Vertex array).VBO及VAO区别 1.glVertex 最原始的设置顶点方法,在glBegin和glEnd之间 ...
- C++ vector和list的区别
1.vector数据结构vector和数组类似,拥有一段连续的内存空间,并且起始地址不变.因此能高效的进行随机存取,时间复杂度为o(1);但因为内存空间是连续的,所以在进行插入和删除操作时,会造成内存 ...
- C++ 顺序容器 vector list deque 之比较
在C++标准库中定义了三种顺序容器类型:vector,list和deque.所谓顺序容器就是根据位置来存储和访问元素,元素的排列次序与元素的值无关,而是由元素添加到容器的次序决定的. vector的底 ...
随机推荐
- 使用Mybatis做批量插入
最近有个需求,将excel的数据导入的数据库的这个一个操作. 工作主要分为:解析excel,将excel中的数据单条循环插入数据库. 使用框架:mybatis+spring 使用过Mybatis的人都 ...
- MVC模型绑定
在项目中使用MVC的时候,我们无需像WebForm那样手动获取值再赋值到Model上,这得益于MVC的模型绑定,下面就介绍下复杂类型的模型绑定 Controller: public class Hom ...
- CSS基本属性—文本属性和背景属性
一.CSS常用文本属性 [css中的颜色表示方式] 1.直接使用颜色的单词表示:red.green.blue 2.使用颜色的十六进制表示:#ff0000,#00ff00: 六位数,两两 ...
- [ARC100]E:Or Plus Max(FZT)
https://arc100.contest.atcoder.jp/tasks/arc100_c 一个很自然的想法是,对于每个K求出i or j=k的所有a[i]+a[j]的最大值ans[k],答案就 ...
- POJ 1113 Wall(凸包)
[题目链接] http://poj.org/problem?id=1113 [题目大意] 给出一个城堡,要求求出距城堡距离大于L的地方建围墙将城堡围起来求所要围墙的长度 [题解] 画图易得答案为凸包的 ...
- Bootstrap-table自定义可编辑每页显示记录数
写在前面: 最近在做的person功能,由于后期系统中person人数较多,不利用查找person,故需求方将要求可以自己编辑每页显示的数目,而不是固定的写死每页显示的数目. 下面先来看下bootsr ...
- Problem B: 零起点学算法17——2个数比较大小
#include<stdio.h> int main() { int n,m; while(scanf("%d %d",&n,&m)!=EOF) if( ...
- centos 7.3systemctl工具
http://www.cnblogs.com/tswcypy/p/4479153.html
- 网络抓包工具Wireshark和Fidder
http://fangxin.blog.51cto.com/1125131/735178 http://blog.csdn.net/jiangwei0910410003/article/details ...
- OpenStack手动制作CentOS 7 KVM镜像
在前面讲解KVM的时候,我们已经学习了如何制作KVM镜像,那么制作OpenStack使用的镜像和KVM是有一些区别的. 1. 下载CentOS 7官方ISO安装镜像这里使用国内阿里云的镜像源进行 ...