首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一文了解STL容器deque类

一文了解STL容器deque类

作者头像
海盗船长
发布2020-08-27 17:38:04
6610
发布2020-08-27 17:38:04
举报

1.deque类的介绍和使用

1.1 deque的介绍

  1. deque是双端队列不规则的首字母缩写,双端队列是动态大小的序列式容器,其可以像两端进行伸缩。
  2. 特定的库可以以不同的方式实现deque,但通常都是一种动态数组。不论在何种情况下,它都允许通过、随机访问迭代器直接访问单个元素,可以根据需要动态的伸缩。
  3. 因此,deque提供了一些与vector相似的功能,但deque在头部和尾部进行数据插入和删除操作更加高效。与vector不同的是,deque不能保证所有的元素存储在连续的空间中,在deque中通过指针加偏移量方式访问元素可能会导致非法的操作。
  4. vector与list提供了相似的接口,因此其具有类似的用途,但是内部的实现原理不同:vector使用使用了动态数组,该数组通常需要动态增长;deque中的元素可能分散在不同的存储块中,在deque中保存了一些必要的信息,通常用来在常数范围内直接访问deque中的任何一个元素,所以deque的内部实现比vector复杂,但是这些额外信息使得dque在某些情况下增长更加的高效,特别是在序列比较大,重新分配成本比较高的情况下。
  5. 除了在频繁在头部或尾部进行插入和删除操作外,deque比list和forward_list的性能更差。

2. deque的使用

2.1 deque的构造

函数声明

接口说明

deque()

构造空的双端队列

deque(size_type n, const value_type& val = value_type())

用n个值为val的元素构造双端队列

deque(InputIterator first, InputIterator last)

用[first, last)的区间构造双端队列

deque(const deque& x)

双端队列的拷贝构造函数

2.2 deque的迭代器

双端队列底层是一段假象的连续空间,实际是分段连续的,为了维护其“整体连续”的假象,落在了deque的迭代器身上。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

函数声明

接口说明

iterator begin()

返回deque起始位置迭代器

iterator end()

返回deque最后一个元素下一个位置的迭代器

reverse_iterator rbegin()

返回deque起始位置的反向迭代器(即end())

reverse_iterator rend()

返回deque最后一个元素下一个位置的反向迭代器(begin())

const_iterator cbegin() const

返回deque起始位置的const迭代器

const_iterator cend() const

返回deque最后一个元素下一个位置的const迭代器

const_reverse_iterator crbegin() const

返回deque起始位置的const反向迭代器(即crend())

const_reverse_iterator crend() const

返回deque最后一个元素下一个位置的const反向迭代器(crbegin())

2.3 deque的容量操作

函数声明

接口说明

size_type size() const

返回deque中有效元素个数

bool empty ( ) const

检测deque是否为空,是返回true,否则返回false

void resize ( size_type sz, T c = T());

将deque中的元素改变到sz,多出的空间用c填充

2.4 deque的元素访问操作

函数声明

接口说明

reference operator[] (size_type n)

返回deque中n位置上元素的引用

const_reference operator[] (size_type n) const

返回deque中n位置上元素的const 引用

reference front()

返回deque中首元素的引用

const_reference front() const

返回deque中首元素的const引用

reference back()

返回deque中最后一个元素的引用

const_reference back() const

返回deque中最后一个元素的const引用

2.4 deque中修改操作

函数声明

接口说明

void push_back(const value_type& val)

deque尾部插入元素val

void pop_back()**

删除deque尾部元素

void push_front (const value_type& val)

deque头部插入元素val

void pop_front()

删除deque头部元素

iterator insert (iterator position, const value_type& val)

在deque的position位置插入值为val的元素

void insert (iterator position, size_type n, const value_type& val)

在deque的position位置插入n个值为val的元素

void insert (iterator position, InputIterator first, InputIterator last)

在deque的position位置插入[first, last)区间中的元素

iterator erase (iterator position)

删除deque中position位置的元素,并返回该位置的下一个位置

iterator erase (iterator first, iterator last)

删除deque中[first, last)区间中的元素,并返

回last位置

void swap (deque& x)

交换两个deque中的内容

void clear()

将deque中的元素清空

iterator emplace (const_iterator position, Args&&… args)

在deque的position位置构造元素,将元素所需内容通过参数类表传入

void emplace_front (Args&&… args)

在deque的头部构造元素,元素的参数通过参数列表传入

void emplace_back (Args&&… args)

在deque的尾部构造元素,元素的参数通过参数列表传入

3 deque中接口应用实例

#include<iostream>
#include<deque>
using namespace std;
void PrintDeque(const std::deque<int>& d){
	for (auto n : d){
		cout << n << " ";
	}
	cout << endl;
}
//测试deque的构造函数
void TestDeque1(){
	std::deque<int> d1;
	PrintDeque(d1);
	std::deque<int> d2(5, 10);
	PrintDeque(d2);
	std::deque<int> d3(d2.begin(), d2.end());
	PrintDeque(d3);
	int array[] = { 3, 24, 35, 46, 3, 7, 54, 32, 23, 345, 6, 7, 6554, 23 };
	std::deque<int> d5(array, array+sizeof(array) / sizeof(array[0]));
	PrintDeque(d5);
	std::deque<int> d4(d5);
	PrintDeque(d4);
}

//测试deque的迭代器
void TestDeque2(){
	int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
	std::deque<int> d(array, array + sizeof(array) / sizeof(array[0]));

	// 利用正向迭代器打印deque中的元素
	for (auto it = d.cbegin(); it != d.cend(); ++it)
		cout << *it << " ";
	cout << endl;

	auto cit = d.cbegin();
	//*it = 100;   该条语句编译失败,it为const迭代器,其指向空间元素值不能修改


	// 利用反向迭代器逆向打印deque中的元素
	for (auto it = d.crbegin(); it != d.crend(); ++it)
		cout << *it << " ";
	cout << endl;
}

void TestDeque3()
{
	// 列表方式初始化,C++11语法
	deque<int> d1{ 3, 4, 5 };

	// 在deque的尾部插入5,头部插入1,并打印
	d1.push_back(6);
	d1.push_front(2);
	PrintDeque(d1);
	cout << d1.size() << endl;
	cout << d1.front() << endl;
	cout << d1.back() << endl;

	// 在deque的尾部构造6,头部构造0
	// 注意:如果是内置类型元素,
	//      emplace_back与push_back emplace_front与push_front的效率形同
	//      如果是自定义类型元素
	//      emplace_back/emplace_front的效率更高,这两个操作直接在尾部或者头部构造元素
	//      push_back/push_front的效率低,该操作时先将元素构造好,然后拷贝到尾部或头部
	d1.emplace_back(7);
	d1.emplace_front(1);
	PrintDeque(d1);

	// 在deque的begin位置插入元素0
	d1.insert(d1.begin(), 0);
	PrintDeque(d1);

	// 删除deque首部与尾部元素
	d1.pop_front();
	d1.pop_back();
	d1.erase(d1.begin());
	PrintDeque(d1);

	// 将deque中的元素清空
	d1.clear();
	cout << d1.size() << endl;
}
int main()
{
	//TestDeque1();
	//TestDeque2();
	TestDeque3();
	system("pause");
	return 0;
}

// 问题:如果要对deque中的元素进行排序,以下的效率高吗?
#include <algorithm>
#include <deque>
void TestDequeSort()
{
	int array[] = { 5, 2, 1, 9, 6, 3, 8, 7, 4, 0 };
	deque<int> d(array, array + sizeof(array) / sizeof(array[0]));
	PrintDeque(d);

	// 利用标准库中的算法对deque中的元素进行升序排序
	sort(d.begin(), d.end());
	PrintDeque(d);
}

/*
上述对deque中排序操作的效率是非常低的,当对deque排序时,需要多次对deque中的元素进行整体遍历,而
deque中的元素整体遍历时效率比较低,这是因为deque底层的空间不连续,如果要进行整体遍历,在某段空间的
默认或首部时,必须要计算下一段或者前一段空间的位置,导致deque的效率比较底下。
*/

4. deque的应用场景

deque最大的应用,就是用其作为标准库中stack和queue的底层结构。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-04-06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.deque类的介绍和使用
    • 1.1 deque的介绍
      • 2. deque的使用
        • 2.1 deque的构造
        • 2.2 deque的迭代器
        • 2.3 deque的容量操作
        • 2.4 deque的元素访问操作
        • 2.4 deque中修改操作
      • 3 deque中接口应用实例
        • 4. deque的应用场景
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档