【STL】Deque容器

deque

0.deque(双端队列)容器介绍

头文件

#include <deque>

插入

deque 在尾部和头部插入或移除元素非常迅速,在中间插入比较费时,具有双端扩缩能力的序列容器,与 Vector 相反,不是相接存储的,是由一段又一段等长的连续空间构成的在这里插入图片描述

随机存取

支持 [target] 或者 at(target) ,与接口上与 Vector 有许多相似之处。元素地址可能不是连续的,通过运算符重载实现伪连续。

1.deque容器操作

deque 容器之比 Vector 容器多两个函数,其余操作一样

deque.push_front(elem);  //容器头部插入一个元素
deque.pop_front(); //删除头部第一个元素

2.deque 对比 vector

  1. 底层数据结构:
    • deque: 双端队列使用多个块(chunks)存储元素,每个块是一个固定大小的数组。在内部,deque 由一系列块组成,每个块都是一个独立的数组,可以在两端进行快速插入和删除。
    • vector: 动态数组是一个连续的存储空间,元素在内存中是依次排列的。它支持在末尾的快速插入和删除,但在中间或开头插入或删除元素时可能会导致其他元素的移动。
  2. 内存分配:
    • deque: 由于deque使用多个块,它的内存分配可以更加灵活,每个块可以分配自己的内存。这意味着在插入或删除元素时,不需要移动整个数据结构,而只需移动块。
    • vector: 动态数组的内存是连续的,因此在插入或删除元素时,可能需要移动整个数组的元素,导致性能开销。
  3. 随机访问性能:
    • deque: 随机访问性能较差,因为要通过指针跳转到正确的块,然后再在块内进行访问。这可能导致对元素的间接引用。
    • vector: 由于元素在内存中是连续排列的,因此支持快速的随机访问。
  4. 迭代器失效:
    • deque: 在deque的头部进行插入或删除不会使迭代器失效,但在中间或尾部进行插入或删除可能会导致某些迭代器失效。
    • vector: 在vector中,插入或删除操作可能导致所有在该位置之后的迭代器失效。
  5. 空间效率:
    • deque: 由于使用了多个块,deque可能会占用更多的空间,因为每个块都需要一些额外的管理开销。
    • vector: 动态数组通常更为紧凑,因为它不需要额外的块管理开销。
  6. 插入和删除性能:
    • deque: 在两端进行插入和删除的性能较好,而在中间进行插入和删除的性能较差。
    • vector: 在末尾进行插入和删除的性能较好,而在中间或开头进行插入和删除的性能较差。

3.什么时候使用?

使用 deque 的情况:

  1. 频繁在两端进行插入和删除: 如果你需要在序列的两端(头部和尾部)进行高效的插入和删除操作,而不关心中间位置的性能,那么 deque 是一个不错的选择。
  2. 对迭代器失效有较高容忍度: 如果你的算法对迭代器失效的容忍度较高,因为在 deque 中插入或删除元素可能导致某些迭代器失效,那么可以考虑使用 deque。
  3. 空间效率相对次要: 如果对空间效率的要求相对较低,因为 deque 可能占用更多的内存,那么可以考虑使用它。

使用 vector 的情况:

  1. 顺序访问和随机访问较多: 如果你的操作主要涉及顺序访问或随机访问元素,并且你对在两端进行插入和删除的性能有一定的容忍度,那么 vector 是一个更为适合的选择。
  2. 对迭代器失效敏感: 如果你的算法对迭代器失效敏感,因为在 vector 中插入或删除元素可能导致所有在该位置之后的迭代器失效,那么可以考虑使用 vector。
  3. 对内存占用有严格要求: 如果内存占用是一个关键因素,因为 vector 通常更为紧凑,那么选择它可能更合适。
  4. 在末尾进行频繁插入和删除: 如果你的主要操作是在序列末尾进行频繁的插入和删除,而不涉及序列头部或中间的操作,那么 vector 的性能可能更好。

4.总结操作函数

  1. 构造和初始化:
    • 默认构造函数:deque<T> d;
    • 指定初始大小的构造函数:deque<T> d(size);
    • 使用范围构造函数:deque<T> d(begin, end);
    • 拷贝构造函数:deque<T> d(otherDeque);
  2. 元素访问:
    • at(index):返回指定索引位置的元素,抛出越界异常。
    • operator[]:返回指定索引位置的元素,不进行越界检查。
    • front():返回第一个元素的引用。
    • back():返回最后一个元素的引用。
  3. 修改容器:
    • push_back(value):在尾部插入元素。
    • push_front(value):在头部插入元素。
    • pop_back():移除尾部元素。
    • pop_front():移除头部元素。
    • emplace_back(args...):在尾部原地构造元素。
    • emplace_front(args...):在头部原地构造元素。
  4. 容器的大小和清空:
    • size():返回容器中元素的个数。
    • empty():检查容器是否为空。
    • resize(newSize):改变容器的大小,可以增加或减少元素。
    • clear():移除所有元素,使容器为空。
  5. 插入和删除:
    • insert(position, value):在指定位置插入元素。
    • erase(position):移除指定位置的元素。
    • erase(begin, end):移除指定范围内的元素。
  6. 迭代器:
    • begin()end():返回指向容器起始和结束的迭代器。
    • rbegin()rend():返回指向容器逆向起始和结束的迭代器。
  7. 其他操作:
    • swap(deque1, deque2):交换两个 deque 的内容。
    • assign(count, value):用指定的值替换容器的内容。
    • assign(begin, end):用指定范围内的值替换容器的内容。
  8. Deque 特有操作:
    • push_front(value):在头部插入元素。
    • pop_front():移除头部元素。
    • emplace_front(args...):在头部原地构造元素。
  • 22
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值