deque

一、deque

1.1 deque的原理介绍

**deque(双端队列):是一种双开口的“连续空间”的数据结构。**双开口的含义是:可以在头尾两端进行插入和删除操作,并且时间复杂度是O(1)的,与vector相比,头插效率高,不需要搬移元素;与list比较空间利用率高。

vector:连续的物理结构,优势:支持下标访问,劣势:扩容头部插入删除的效率低。

list:一块一块的分散结构,优势:按需申请释放任意位置插入删除的效率高,劣势:下标访问效率低,在标准库的实现中是不支持下标访问的。

以下是deque的图示:

deque并不是真正连续的空间,而是由一段断的连续的小空间拼接而成的,实际deque是类似于一个动态的二维数组的结构的,其底层结构如下图所示:

双端队列底层是一段假象的连续空间,实际上是分段连续的,为了维护其“整体连续”以及随机访问的假象,落在了deque的迭代器身上,因此deque的迭代器的实现比较复杂,如下图所示:

deque借助迭代器维持假象的连续结构的原理:

中控数组的本质就相当于一个指针数组,中控数组中的每个元素指向一个小数组,从而实现一个连续空间的假象,其实是有一段段小的连续空间通过中控数组联系起来的。

1.2 deque的缺陷

与vector比较,deque的优势是:头部插入和删除时,不用挪动元素,效率比较高,而且在扩容时也不需要挪动元素,因此效率是一定比vector高的。

与list比较 ,deque的底层是一个伪连续空间,空间利用率高,不需要存储额外字段。

致命缺陷deque不适合用来遍历,因为在遍历时deque的迭代器需要频繁的检测其是否移动到某段小空间的边界,导致效率低下,但是在序列式的场景下,可能要经常进行遍历,因此在实际中对于线性结构大多数的情况下还是优先使用vector和list,deque的引用并不多,deque作为stack和queue的底层数据结构是比较好的

二、为何选择deque作为stack和queue的默认容器

1,stack和queue是不需要进行遍历的(因此stack和queue是没有迭代器的),只需要固定的一端或者两端进行操作。

2,在stack中元素增长时,deque比vector的效率高(因为扩容时不需要进行挪动数据);queue中的元素增长时deque不仅效率高,而且内存使用率同样也高。

对于在作为stack和queue的底层容器是正好结合了deque的优点而且完美的避开了它的缺点。

三、deque的使用

3.1 stack的模拟实现:

template<class T, class Con = deque<T>>
//栈
class stack
{

public:
	//栈的构造
	stack() {}
	//push直接借助传入容器的push即可
	void push(const T& x)
	{
		c.push_back(x);
	}
	//pop借助容器的pop将栈顶元素即数组中的最后一个元素pop掉
	void pop()
	{
		c.pop_back();
	}
	//返回栈顶元素即数组的最后一个元素
	T& top()
	{
		return c.back();
	}

	const T& top()const
	{
		return c.back();
	}
	//返回栈内的元素个数,直接返回容器的size即可
	size_t size()const
	{
		return c.size();
	}
	//判断栈是否为空,直接判断容器是否为空即可
	bool empty()const
	{
		return c.empty();
	}

private:

	Con c;

};

3.2 queue的模拟实现:

template<class T, class Con = deque<T>>
//队列
class queue
{
public:
	//队列的构造
	queue() {}
	//进队列,先进先出,队尾进队头出,选择头插
	void push(const T& x)
	{
		c.insert(c.begin(), x);
	}
	//出队列尾删即可
	void pop()
	{
		c.pop_back();
	}
	//返回队尾元素,即返回容器的头
	T& back()
	{
		return c.front();
	}

	const T& back()const
	{
		return c.front();
	}
	//返回队头元素,即返回容器的尾
	T& front()
	{
		return c.back();
	}

	const T& front()const
	{
		return c.back();
	}
	//返回队列中的有效数据,即返回容器的size
	size_t size()const
	{
		return c.size();
	}
	//判断队列是否为空,即判断容器是否为空即可
	bool empty()const
	{
		return c.empty();
	}

private:

	Con c;

};

四、总结

1.deque 的结构,支持下标随机访问,偶尔使用还行,但是大量访问的效率远不及vector

2.deque的insert和erase是需要考虑挪动数据的,因此效率不高。

3.deque的头尾插入删除效率很高,STL库中的stack和queue的底层是基于deque实现的。

结论:deque作为stack和queue的底层容器是很适合的。

ector**

2.deque的insert和erase是需要考虑挪动数据的,因此效率不高。

3.deque的头尾插入删除效率很高,STL库中的stack和queue的底层是基于deque实现的。

结论:deque作为stack和queue的底层容器是很适合的。

相关推荐

  1. <span style='color:red;'>deque</span>

    deque

    2024-06-06 03:42:02      30 阅读
  2. STL-deque

    2024-06-06 03:42:02       56 阅读
  3. deque学习笔记

    2024-06-06 03:42:02       27 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-06 03:42:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-06 03:42:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-06-06 03:42:02       82 阅读
  4. Python语言-面向对象

    2024-06-06 03:42:02       91 阅读

热门阅读

  1. 关于焊点检测SJ-BIST)模块实现

    2024-06-06 03:42:02       30 阅读
  2. 日常实习-小米计算机视觉算法岗面经

    2024-06-06 03:42:02       34 阅读
  3. 【Golang】go语言写入数据并保存Excel表格

    2024-06-06 03:42:02       27 阅读
  4. 054、Python 函数的概念以及定义

    2024-06-06 03:42:02       33 阅读
  5. 【安卓配置WebView以允许非HTTPS页面访问摄像头】

    2024-06-06 03:42:02       31 阅读
  6. MySQL并发事务是怎么处理的?

    2024-06-06 03:42:02       29 阅读
  7. 欲除烦恼须无我,各有前因莫羡人

    2024-06-06 03:42:02       21 阅读
  8. Python连接数据库进行数据查询

    2024-06-06 03:42:02       27 阅读
  9. flink Transformation算子(更新中)

    2024-06-06 03:42:02       23 阅读
  10. 探索 Linux 命令 `yum`:软件包管理器的奥秘

    2024-06-06 03:42:02       32 阅读
  11. MAC帧

    MAC帧

    2024-06-06 03:42:02      27 阅读
  12. 力扣70. 爬楼梯

    2024-06-06 03:42:02       27 阅读