deque
-
可以队首和队尾插入,也可以队首和队尾弹出
-
支持随机访问,即可以直接用下标来访问元素。它和vector有点像,因为它可以index索引和at()函数索引,当然,也可以迭代器索引。
-
此外,它可以进行指定尺寸的构造,queue就不可以指定尺寸构造。
构造函数
deque<int> q1;
deque<int> q2(6,8);//6个值为8的成员
deque<int> q3(q2.begin() + 2, q2.end());
deque<int> q4(q2);
迭代器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AuIBjgSo-1669195255380)(C:/Users/l/AppData/Roaming/Typora/typora-user-images/image-20221123160955743.png)]
常用操作
操作明显多于queue和pq
empty(); //判断容器是否为空
clear(); //清空容器的所有数据
size(); //返回容器中的元素的个数
resize(num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。//如果容器变短,则末尾超出容器长度的元素被删除。
resize(num,elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则超出容器长度的元素被删除。
clear(); //清空容器的所有数据
swap();
访问操作
at(int idx); //返回索引idx所指的数据
operator[]; //返回索引idx所指的数据
front(); //返回容器中第一个数据元素
back(); //返回容器中最后一个数据元素
插入删除覆盖
deque<int>::iterator it = bar.begin();
push_back(elem); //在容器尾部添加一个数据
push_front(elem); //在容器头部插入一个数据
pop_back(); //删除容器最后一个数据
pop_front(); //删除容器第一个数据
insert(pos,elem); //在pos位置插入一个elem元素的拷贝,返回新数据的位置。
insert(pos,n,elem); //在pos位置插入n个elem数据,无返回值
insert(pos,beg,end); //在pos位置插入[beg,end)区间的数据,无返回值
erase(beg,end); //删除[beg,end)区间的数据,返回下一个数据的位置。
erase(pos); //删除pos位置的数据,返回下一个数据的位置。
assign(beg, end); //将[beg,end)区间中的数据拷贝赋值给本身。
assign(n,elem); //将n个elem拷贝赋值给本身。
关于push和emplace的区别
https://blog.youkuaiyun.com/jokerMingge/article/details/119736247
C++11
emplace()
emplace_back()
emplace_front()
emplace_cbegin
emplace_crbegin
emplace_cend
emplace_crend ;
shrink_to_fit(); //请求容器减少内存使用以适应其大小。
与其他container的区别
头插
vector对于头部的插入效率低,数据量越大,效率越低,例如头部后有十万个数据,则往头部插入一个数据时,十万个数据都需要往后挪一挪才能在头部插入数据。deque相对而言,对头部的插入删除速度会比vector快。deque在头部和尾部进行数据插入和删除操作更加高效。
如果没有频繁在头部或尾部进行插入和删除操作,deque比list和forward_list的性能更差。
访问
vector访问元素时的速度会比deque快。
存储
与vector不同的是,deque不能保证所有的元素存储在连续的空间中,在deque中通过指针加量方式访问元素可能会导致非法的操作。
vector使用使用动态数组,该数组通常需要动态增长;deque中的元素可能分散在不同的存储块中,在deque中保存一些必要的信息,通常用来在常数范围内直接访问deque中的任何一个元素,所以deque的内部实现比vector复杂,但是这些额外信息使得dque在某些情况下增长更加的高效,特别是在序列比较大,重新分配成本比较高的情况下。
内部工作原理
和 vector 容器采用连续的线性空间不同,deque 容器存储数据的空间是由一段一段等长的连续空间构成,各段空间之间并不一定是连续的,可以位于在内存的不同区域。为了管理这些连续空间,deque 容器用数组存储着各个连续空间的首地址。也就是说,数组中存储的都是指针,指向那些真正用来存储数据的各个连续空间。
通过建立数组,deque 容器申请的这些分段的连续空间就能实现“整体连续”的效果。换句话说,当 deque 容器需要在头部或尾部增加存储空间时,它会申请一段新的连续空间,同时在数组的开头或结尾添加指向该空间的指针,由此该空间就串接到了 deque的头部或尾部。
priority_queue
优先队列是一种会按照默认或自定义的优先级进行自动排序的队列,其特点是优先级高的元素排在队首,低的排在队尾。
创建
数据类型:可以是int、double等基本类型,也可以是自定义的结构体。
容器类型:一般为deque(双端列表)、vector(向量容器),可省略,省略时以vector为默认容器。
pq:优先队列名。
priority_queue< 数据类型,容器类型,优先规则> pq;
priority_queue<int> pq;
priority_queue<int,vector<int>,less<int> > pq; //以less为排列规则(大顶堆,表示顶堆元素比其他都大)
priority_queue<int,vector<int>,greater<int> > pq; //以greater为排列规则(小顶堆,表示顶堆元素比其他都小)
常用操作
pq.push(); //入队
pq.pop(); //出队
pq.size() //返回当前对中元素个数
pq.top(); //优先队列 取队首元素
pq.empty(); //判断是否为空(空返回 1,非空返回 0)
C++11
pq.swap()
pq.emplace()
与queue的区别在于queue有front()和back(),而pq只有top()
queue
(58条消息) C++队列queue用法详解_KEPROM的博客-优快云博客_c++ queue
一般直接用deque。deque的功能比queue更全,而且queue底层也是用deque创建的
创建
queue<数据类型,容器类型> q;
数据类型:可以是int、double等基本类型,也可以是自定义的结构体。
容器类型:一般为deque或者list(双向链表),可省略,省略时以deque为默认容器。
queue<int> q; //使用默认的双端队列为底层容器创建一个空的queue队列对象q,数据元素为int类型。
queue<int,list<int>> q1;
queue<int,list<int>> q2(q1);
/*复制构造函数(queue(const queue&)),用一个queue对象创建新的queue对象。
利用queue对象q1,创建一个以双向链表为底层容器的queue对象q2*/
- 和 stack 一样,queue 也没有迭代器。访问元素的唯一方式是遍历容器内容,并移除访问过的每一个元素。
- 只能队尾插入,队首弹出。
- queue不初始化元素个数或者初始化值
常用操作
q.push(x); //入队,将元素 x 从队尾插入(尾插法)
q.pop(); //出队,删除对首元素,并返回其值
q.size(); //返回队中元素个数
q.front(); //返回队首元素
q.back(); //返回队尾元素
q.empty(); //判断是否为空(空返回 1,非空返回 0)
C++11
q.swap(q2)
q.emplace(x) //入队
empty()函数可以判断队列是否为空,但没有clear来清空,可以创建空的queue用swap函数交换
queue q2;
if (q1.empty()) {
cout << “q1 is empty” << endl;
}
q1.swap(q2);
if (q1.empty()) {
cout << “q1 is empty after swap” << endl;
}