我是靠谱客的博主 机灵火,最近开发中收集的这篇文章主要介绍双端队列(deque)总结(会更新)一.deque,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 一.deque
    • 一.deque简介
    • 二.deque特性
      • (1).deque与vector的不同
      • (2)deque和vector相似的特性:
    • 三.基本函数实现
      • 1.构造函数
      • 2.添加函数
      • 3.删除函数
      • 4.遍历函数
      • 5.判断函数
      • 6.大小函数
      • 7.其他函数
      • 8.总结


一.deque

  • 适用于既要频繁随机访问,又要关心两端数据的插入与删除的场景。

一.deque简介

deque是双向开口的连续性存储空间。虽说是连续性存储空间,但这种连续性只是表面上的,实际上它的内存是动态分配的,它在堆上分配了一块一块的动态储存区,每一块动态存储去本身是连续的,deque自身的机制把这一块一块的存储区虚拟地连在一起。
它首次插入一个元素,默认会动态分配512字节空间,当这512字节空间用完后,它会再动态分配自己另外的512字节空间,然后虚拟地连在一起。deque的这种设计使得它具有比vector复杂得多的架构、算法和迭代器设计。它的性能损失比之vector,是几个数量级的差别。所以说,deque要慎用。

二.deque特性

deque是连续线性空间。但这种连续不同于数组和vector的连续,deque只是逻辑上的连续空间,它把一块一块独立的空间逻辑地连在一起,仿佛整个deque空间是一块完整的连续空间
deque容器是C++标准模版库(STL,Standard Template Library)中的部分内容。deque容器类与vector类似,支持随机访问和快速插入删除,它在容器中某一位置上的操作所花费的是线性时间。与vector不同的是,deque还支持从开始端插入数据
支持随机访问,即支持[]以及at(),但是性能没有vector好。
可以在内部进行插入和删除操作,但性能不及list。

(1).deque与vector的不同

1、两端都能够快速插入和删除元素。vector只能在尾端进行。

2、deque的元素存取和迭代器操作会稍微慢一些。因为deque的内部结构会多一个间接过程。

3、迭代器是特殊的智能指针,而不是一般指针。它需要在不同的区块之间跳转。

4、deque可以包含更多的元素,其max_size可能更大。因为不止使用一块内存。

5、不支持对容量和内存分配时机的控制。

6、deque的内存区块不再被使用时,会被释放。deque的内存大小是可缩减的。不过,是不是这么做以及怎么做由实作版本定义。

(2)deque和vector相似的特性:

1、在中间部分插入和删除元素相对较慢,因为所有元素都要被移动。

2、迭代器属于随即存取迭代器。

最好采用deque的情形:

1、需要在两端插入和删除元素。

2、无需引用容器内的元素。

3、要求容器释放不再使用的元素。

三.基本函数实现

使用前添加函数头#include<deque>

1.构造函数

  • deque<Elem> c 创建一个空的deque
deque<int > q;创建int型数据,队列名为q
  • deque<Elem> c1(c2) 复制一个deque。
deque<int >q1;
deque<int >q2(q1);
  • deque<Elem> c(n) 创建一个deque,含有n个数据,数据均已缺省构造产生。
deque<int >q(5);
  • deque<Elem> c(n, elem) 创建一个含有n个elem拷贝的deque。
deque<int >q(2,2);
while(q.size())
{
cout<<q.front()<<' ';
q.pop_front();
}
输出:2 2
  • deque<Elem> c(beg,end) 创建一个以[beg;end)区间的deque。
	deque<int >q;
deque<int >q2(q.begin(),q.end());
  • ~deque<Elem>() 销毁所有数据,释放内存

2.添加函数

  • deque.push_back(elem); //在容器尾部添加一个数据
deque<int >q(2,2);
q.push_back(1);
while(q.size())
{
cout<<q.front()<<' ';
q.pop_front();
}
输出:2 2 1
  • deque.push_front(elem); //在容器头部插入一个数据
deque<int >q(2,2);
q.push_front(1);
while(q.size())
{
cout<<q.front()<<' ';
q.pop_front();
}
输出:1 2 2
  • emplace(); //在队列指定的元素位置前插入新的元素
  • emplace_back(); //在队列尾部增加新的元素
deque<int >q(2,2);
q.emplace_back(1);
while(q.size())
{
cout<<q.front()<<' ';
q.pop_front();
}
输出:2 2 1
  • emplace_front();// 在队列头部增加新的元素
deque<int >q(2,2);
q.emplace_front(1);
while(q.size())
{
cout<<q.front()<<' ';
q.pop_front();
}
输出:1 2 2
  • deque.insert(pos,elem); //在pos位置插入一个elem元素的拷贝,返回新数据的位置。
deque<int >q(2,2);
q.insert(q.begin()+1,1);
while(q.size())
{
cout<<q.front()<<' ';
q.pop_front();
}
输出:2 1 2
  • deque.insert(pos,n,elem); //在pos位置插入n个elem数据,无返回值。
deque<int >q(2,2);
q.insert(q.begin()+1,2,1);
while(q.size())
{
cout<<q.front()<<' ';
q.pop_front();
}
输出:2 1 1 2
  • deque.insert(pos,beg,end); //在pos位置插入[beg,end)区间的数据,无返回值。
deque<int >q(4,2),p(2,5);
q.insert(q.begin()+1,p.begin(),p.end());
while(q.size())
{
cout<<q.front()<<' ';
q.pop_front();
}
输出:2 5 5 2 2 2
 1
deque<int> d {1,2,3,4,5};
2
deque<int>::iterator it;
3
cout << "insert before:" ;
4
for(it=d.begin();it!=d.end();it++){
5
cout << *it << " ";
6
}
7
cout << endl;
8
d.insert(d.end(),22);
9
d.insert(d.end(), 3,88);
10
int a[5] = {1,2,3,4,5};
11
d.insert(d.begin(),a,a+3);
12
cout << "insert after:" ;
13
for(it=d.begin();it!=d.end();it++){
14
cout << *it << " ";
15
}
16
cout << endl;

3.删除函数

  • deque.pop_back(); //删除容器最后一个数据
deque<int >q(4,2);
//q.pop_back();
while(q.size())
{
cout<<q.front()<<' ';
q.pop_front();
}
输出:2 2 2 2
deque<int >q(4,2);
q.pop_back();
while(q.size())
{
cout<<q.front()<<' ';
q.pop_front();
}
输出:2 2 2
  • deque.pop_front(); //删除容器第一个数据
deque<int >q(4,2),p(2,5);
q.insert(q.begin()+1,p.begin(),p.end());
while(q.size())
{
cout<<q.front()<<' ';
q.pop_front();
}
输出:2 5 5 2 2 2
deque<int >q(4,2),p(2,5);
q.insert(q.begin()+1,p.begin(),p.end());
q.pop_front();
while(q.size())
{
cout<<q.front()<<' ';
q.pop_front();
}
输出:5 5 2 2 2
  • deque.clear(); //移除容器的所有数据
1
deque<int> d {1,2,3,4,5};
2
deque<int>::iterator it;
3
cout << "clear before:" ;
4
for(it=d.begin();it!=d.end();it++){
5
cout << *it << " ";
6
}
7
cout << endl;
8
d.clear();
9
cout << "clear after:" ;
10
for(it=d.begin();it!=d.end();it++){
11
cout << *it << " ";
12
}
13
cout << endl;
  • deque.erase(beg,end); //删除[beg,end)区间的数据,返回下一个数据的位置。
  • deque.erase(pos); //删除pos位置的数据,返回下一个数据的位置。
1
deque<int> d {1,2,3,4,5};
2
d.erase(d.begin());
3
deque<int>::iterator it;
4
cout << "erase(pos) after:" ;
5
for(it=d.begin();it!=d.end();it++){
6
cout << *it << " ";
7
}
8
cout << endl;
9
d.erase(d.begin(), d.begin()+3);
10
cout << "erase(beg,end) after:" ;
11
for(it=d.begin();it!=d.end();it++){
12
cout << *it << " ";
13
}
14
cout << endl;

4.遍历函数

  • deque.at(idx); //返回索引idx所指的数据,如果idx越界,抛出out_of_range。
1
deque<int> d {1,2,3,4,5};
2
cout << "d.at(pos):" << d.at(2);
3
return 0;
  • deque[idx]`; //返回索引idx所指的数据,如果idx越界,不抛出异常,直接出错。
deque<int >q(2,2),p(2,5);
q.insert(q.begin()+2,p.begin(),p.end());
int c=q[2];
cout<<c;
输出:5
  • deque.front(); //返回第一个数据。
deque<int >q(4,2),p(2,5);
q.insert(q.begin()+1,p.begin(),p.end());
int c=q.front();
cout<<c;
输出:2
  • deque.back(); //返回最后一个数据
deque<int >q(2,2),p(2,5);
q.insert(q.begin()+2,p.begin(),p.end());
int c=q.back();
cout<<c;
输出:5

5.判断函数

  • deque.empty(); //判断容器是否为空
1
deque<int> d {1,2,3,4,5};
2
if(!d.empty()){
3
cout << "d is not empty!" << endl;
4
}else{
5
cout << "d is empty!" << endl;
6
}
7
return 0;

6.大小函数

  • deque.size(); //返回容器中元素的个数
1
deque<int> d {1,2,3,4,5};
2
cout << "d.size():" << d.size() << endl;
3
return 0;
  • deque.resize(num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
 1
deque<int> d {1,2,3,4,5};
2
cout << "d.size():" << d.size() << endl;
3
d.resize(d.size()+5);
4
cout << "d.resize() after:" << d.size() <<endl;
5
deque<int>::iterator it;
6
cout << "resize() after:" ;
7
for(it=d.begin();it!=d.end();it++){
8
cout << *it << " ";
9
}
10
cout << endl;
  • deque.resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
1
deque<int> d {1,2,3,4,5};
2
cout << "d.size():" << d.size() << endl;
3
d.resize(d.size()+5);
4
cout << "d.resize() after:" << d.size() <<endl;
5
deque<int>::iterator it;
6
cout << "resize() after:" ;
7
for(it=d.begin();it!=d.end();it++){
8
cout << *it << " ";
9
}
10
cout << endl;
  • max_size()返回c容器可能存放元素的最大数量
1
deque<int> d {1,2,3,4,5};
2
cout << "d.max_size():" << d.max_size() << endl;
3
return 0;

7.其他函数

  • get_allocator() 返回双向队列的配置器
  • deque.begin(); //返回容器中第一个元素的迭代器。
  • deque.end(); //返回容器中最后一个元素之后的迭代器。一般与别的函数结合使用
deque<int> d {1,2,3,4,5};
deque<int>::iterator it;
for(it=d.begin();it!=d.end();it++){
cout << *it << " ";
}
cout << endl;
  • deque.rbegin(); //返回容器中倒数第一个元素的迭代器。返回指向反向队列的第一个元素的迭代器(即原队列的最后一个元素)
  • deque.rend(); //返回容器中倒数最后一个元素之后的迭代器。返回指向反向队列的最后一个元素的下一个位置(即原队列的第一个元素的前一个位置).一般与别的函数结合使用
1
deque<int> d {1,2,3,4,5};
2
deque<int>::reverse_iterator it;
3
for(it=d.rbegin();it!=d.rend();it++){
4
cout << *it << " ";
5
}
6
cout << endl;
  • operator=赋值运算符重载
deque<int> d1 {1,2,3,4,5},d2;
d2 = d1;
deque<int>::iterator it;
for(it=d2.begin();it!=d2.end();it++){
cout << *it << " ";
}
cout << endl;
  • deque.assign(beg,end); //将[beg, end)区间中的数据拷贝赋值给本身。注意该区间是左闭右开的区间。
  • deque.assign(n,elem); //将n个elem拷贝赋值给本身。
1
deque<int> d1 {1,2,3,4,5},d2;
2
d2.assign(2, 8);
3
deque<int>::iterator it;
4
cout << "d2.assign(n,num):";
5
for(it=d2.begin();it!=d2.end();it++){
6
cout << *it << " ";
7
}
8
d2.assign(d1.begin(), d1.begin()+3);
9
cout << "d2.assign(beg,end):";
10
for(it=d2.begin();it!=d2.end();it++){
11
cout << *it << " ";
12
}
13
cout << endl;
  • deque.swap(deq); // 将vec与本身的元素互换c1.swap(c2)交换容器c1,c2;
    swap(c1,c2)同上。
1
deque<int> d1 {1,2,3,4,5},d2,d3;
2
d1.swap(d2);
3
deque<int>::iterator it;
4
cout << "d1 swap after:" ;
5
for(it=d1.begin();it!=d1.end();it++){
6
cout << *it << " ";
7
}
8
cout << endl;
9
cout << "d2 swap after:" ;
10
for(it=d2.begin();it!=d2.end();it++){
11
cout << *it << " ";
12
}
13
cout << endl;
14
15
swap(d3,d2);
16
cout << "d3 swap after:" ;
17
for(it=d3.begin();it!=d3.end();it++){
18
cout << *it << " ";
19
}
20
cout << endl;
  • c.operator[]下标运算符重载
1
deque<int> d {1,2,3,4,5};
2
cout << "d[2]:" << d[2];
3
return 0;

8.总结

1.c.begin()返回指向第一个元素的迭代器
2.end()返回指向最后一个元素下一个位置的迭代器
3.c.rbegin()返回指向反向队列的第一个元素的迭代器(即原队列的最后一个元素)
4.c.rend()返回指向反向队列的最后一个元素的下一个位置(即原队列的第一个元素的前一个位置)
5.operator=赋值运算符重载
6.c.assign(n,num)将n个num拷贝复制到容器
7 c.assign(beg,end)将[beg,end)区间的数据拷贝复制到容器c
8.c.at(pos)返回索引为pos的位置的元素,会执行边界检查,如果越界抛出out_of_range异常
9.c.operator[]下标运算符重载 c.empty()判断c容器是否为空
10.c.front()返回c容器的第一个元素
11.c.size()返回c容器中实际拥有的元素个数
12.c.back()返回c容器的最后一个元素
13.c.size()返回c容器中实际拥有的元素个数
14.c.clear()清除c容器中拥有的所有元素
15.c.insert(pos,num)在pos位置插入元素num
16.c.insert(pos,n,num)在pos位置插入n个元素num
17.c.insert(pos,beg,end)在pos位置插入区间为[beg,end)的元素
18.c.erase(pos)删除pos位置的元素
19.erase(beg,end)删除区间为[beg,end)的元素
20.c.erase(beg,end)删除区间为[beg,end)之间的元素
21.c.push_back(num)在末尾位置插入元素
22.c.pop_back()删除末尾位置的元素 c.push_front(num)在开头位置插入元素
23.c.pop_front()删除开头位置的元素
24.c.resize(num)从新定义容器的大小
24.c1.swap(c2)交换容器c1,c2;
swap(c1,c2)同上。
25.重载运算符
.operator== .
operator!=
operator<
operator<=
operator>
operator>=

用法作用
q.begin(),q.end()返回deque的首、尾迭代器
q.front(),q.back()返回deque的首、尾元素
q.push_back()从队尾入队一个元素
q.push_front()从队头入队一个元素
q.pop_back()从队尾出队一个元素
q.pop_front()从队头出队一个元素
q.clear()清空队列

除了这些用法之外,deque比queue更优秀的一个性质是它支持随机访问,即可以像数组下标一样取出其中的一个元素。
即:q[i]。

1
deque<int> d {1,2,3,4,5};
2
d.push_back(10);
3
deque<int>::iterator it;
4
cout << "push_back(num):" ;
5
for(it=d.begin();it!=d.end();it++){
6
cout << *it << " ";
7
}
8
cout << endl;
9
10
d.pop_back();
11
cout << "pop_back(num):" ;
12
for(it=d.begin();it!=d.end();it++){
13
cout << *it << " ";
14
}
15
cout << endl;
16
17
d.push_front(10);
18
cout << "push_front(num):" ;
19
for(it=d.begin();it!=d.end();it++){
20
cout << *it << " ";
21
}
22
cout << endl;
23
24
d.pop_front();
25
cout << "pop_front(num):" ;
26
for(it=d.begin();it!=d.end();it++){
27
cout << *it << " ";
28
}
29
cout << endl;
30
return 0;

最后

以上就是机灵火为你收集整理的双端队列(deque)总结(会更新)一.deque的全部内容,希望文章能够帮你解决双端队列(deque)总结(会更新)一.deque所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部