deque&list
文章目录
deque 和 list 都是属于序列式容器
与vector有许多相似的功能
序列式容器
- 序列式容器的元素按严格线性排列
- 可按顺序访问它们的位置
- 只有一个前驱和后继
array vector list deque 都属于序列式容器
deque
双端队列(▽)
deque的底层实现是一个链表数组
头文件 #include <deque>
定义:
deque<数据类型> 变量名;
deque<int> que;//定义了一个整型的双端队列;
deque与vector类型,都可以进行数据的访问,插入和删除
相比vector新增函数
deque可以进行高效的头部插入和删除数据
void push_front(); //从头部添加数据
void pop_front(); //从头部删除数据
void emplace_front() //从头部添加数据
相比vector没有的函数,deque由于底层是一个不连续的数组内存之间组成的,所以没有指针内存操作
void capcity() //不能获取内存空间
void reserve() //不能改变空间大小
void shrink_to_fit() //缩减空间大小
//无法将数据给C语言函数使用
void data(); //没有固定的数组指针
容器属性
序列式容器 | 动态数组
Deque特点
- deque是双端队列的数据结构,可以在队首高效的添加和删除元素,这是相对于vector的优势。
- deque内部采用分段连续的内存空间来存储元素,在插入元素的时候随时都可以重新增加一段新的空间并链接起来,因此虽然提供了随机访问操作,但访问速度和vector相比要慢。
- deque并没有data函数,因为deque的元素并没有放在数组中。
- deque因为没有固定的内存空间不提供capacity和reserve操作。
函数相关
void begin(); // 将迭代器返回到开头(增长方向:begin -> end)
void end(); // 将迭代器返回到结尾
void rbegin(); // 返回反向迭代器以反向开始(增长方向:rbegin -> rend)
void rend(); //将反向迭代器返回到反向结束
void cbegin() //将const_iterator返回到开头
// *与begin类似,区别在于begin指向的值可以改变,cbegin指向的值不可改变*
void cend() //将const_iterator返回到开头末尾
void crbegin() //返回const_reverse_iterator以反向开始
void crend() //将const_reverse_iterator返回到反向结束
void swap() // 交换两个容器的内容
void emplace() // 在迭代器位置插入元素
void emplace_front() // 在首部添加一个元素
void emplace_back() // 在尾部添加一个元素
list
list
是一个双向链表
容器属性
-
底层实现是一个双向链表
-
序列式容器
-
list占用的空间比较大
list特点
双向链表list
头文件 #include <list>
使用
//list <类型> 变量名
list<int> li;
list
和deque
的元素在内存的组织形式不同,以链表的形式保存list
也可以在尾部和头部加入元素,因此也支持push_back
和push_front
以及pop_front
和push_back
list
可以高效的在内部插入元素而不需要移动元素list
独有的成员函数remove()
可以移除和参数匹配的元素。list
删除数据的时候会马上回收资源list
在多线程的时候相对比较安全
相比vector新增函数
void push_front(); //从头部插入数据
void pop_front(); //从尾部插入数据
void remove() //删除元素值
void unique(); //删除连续重复的数值
void merge(); //归并两个有序链表
void sort(); //调用list内部的排序算法
没有at()
不能进行内部的随机访问,即不支持[]
操作符和at()
list::iterator 没有 operator+();
list::iterator 没有 operator+=();
capcity(); //不能获取空间长度
resize(); //不能修改长度
insert emplace 的区别
insert 复制一份对象
emplace 直接构造
容器的使用
vector list 和 deque三个不同的序列式容器,都有着不同的应用场景
vector deque list 之间的区别
vector
- 特点:数据全部顺序存储,允许直接访问其任何元素,高效的随机访问,快速的从尾部添加(删除)数据,并且可以返回一个C语言指针
- 底层:是一个地址有序存储的数组,以连续的地址存储
- 缺点:内部插入数据和删除数据的效率低下,内存大小有限,当该数组后的内存空间不够时,需要重新申请一块足够大的内存并进行内存的拷贝,容量有限
deque
- 特点:结合了数组和链表的两个特点,既可快速在序列的首尾相对快速进行元素添加(删除),又可以进行随机访问
- 底层:是一个数组链表,每段数组分段存储在内存中
- 缺点:访问速度略比vector要慢,从中间插入(删除)数据效率低下
list
- 特点:高效的进行内部的插入和删除,并能够真正的从内存中销毁数据,数据插入和删除不会影响其他迭代器的访问
- 底层:是一个双向链表,节点和节点之间进行链接
- 缺点:不支持随机访问,有一定的额外内存
容器之间的转换
迭代器拷贝
普通的容器可以进行迭代器进行拷贝
vector<int> vec ={1,2,3,4,5,6,7,8,9,10}
vector<int> vec2(vec.begin(),vec.end());
vector&deque&list之间的转换
不同的容器之间也可以通过迭代器进行拷贝
//声明一个vector容器
vector<int> vec={1,2,3,4,5,6,7,8,9,10};
//将vector的数据拷贝到list容器中
list<int> li(vec.begin(),vec.end());
//将vector的数据拷贝到deque容器中
deque<int> de(vec.begin(),vec.end());
同时list
和deque
可以反向的拷贝给vector使用
总结
- deque容器的特点
- list容器的特点
- 三个容器之间的区别