当前位置: 首页 > news >正文

C++ STL Deque 高频面试题与答案

目录

Q1: 什么是 C++ STL 中的 deque?

Q2: deque 的内部数据结构是怎样的?

Q3: deque 主要操作的时间复杂度是多少?

Q4: deque 和 vector 有什么主要区别?

Q5: deque 和 list 有什么主要区别?

Q6: deque 的迭代器失效规则是怎样的?

Q7: 什么时候应该使用 deque?


deque(double-ended queue,双端队列)是 C++ STL 中一个非常有用的序列容器。它允许在序列的两端(前端和后端)进行快速的插入和删除操作。

Q1: 什么是 C++ STL 中的 deque

A1: deque 是一个序列容器,它支持在容器的两端(前端和后端)进行高效的插入和删除操作。它也支持通过索引([].at())进行快速的随机访问。

它的行为就像一个 vectorlist 的混合体,提供了类似 vector 的随机访问能力,又具备了类似 list 的两端高效插入/删除能力。

Q2: deque 的内部数据结构是怎样的?

A2: deque 的内部实现通常比 vector 复杂。它不是一块连续的内存。

相反,deque 内部通常由一个“中控器”(或称为“map”,但这里的 map 不是 std::map)来管理。这个中控器是一个指针数组(或指针的指针),它指向多个固定大小的内存块(chunks/blocks)。

  • 中控器(Map): 是一个连续的内存块,存储指向各个数据块的指针。

  • 数据块(Chunks): 是实际存储元素的连续内存块。

当在 deque 的前端或后端插入元素时:

  1. 如果对应方向的数据块未满,元素被直接放入该块。

  2. 如果该数据块已满,deque 会分配一个新的数据块,并将新元素放入,同时在中控器(map)中添加指向这个新数据块的指针。

  3. 如果中控器(map)本身也满了,deque 会分配一个新的、更大的中控器,将旧中控器的内容拷贝过去,然后释放旧中控器。

这种分块的结构使得它可以在两端高效地增长,而不需要像 vector 那样移动所有元素。

Q3: deque 主要操作的时间复杂度是多少?

A3:

操作

时间复杂度

备注

随机访问 ([], .at())

$O(1)$

几乎是 $O(1)$。严格来说,它需要一次中控器索引和一次数据块内偏移,但都是常数时间。

前端插入/删除 (push_front, pop_front)

$O(1)$ (均摊)

均摊复杂度。在大多数情况下是 $O(1)$,但如果需要分配新数据块或扩展中控器,则会产生额外开销。

后端插入/删除 (push_back, pop_back)

$O(1)$ (均摊)

同上。

中间插入/删除

$O(N)$

$N$ 是 deque 中元素的数量。这涉及移动插入/删除点之后(或之前)的所有元素,效率很低。

Q4: dequevector 有什么主要区别?

A4: 这是最常被问到的问题之一。

特性

vector (动态数组)

deque (双端队列)

内存布局

连续内存 (所有元素在一整块内存中)

分块的连续内存 (通过中控器管理多个数据块)

前端插入/删除

$O(N)$ (效率极低,需移动所有元素)

$O(1)$ (均摊,非常高效)

后端插入/删除

$O(1)$ (均摊)

$O(1)$ (均摊)

中间插入/删除

$O(N)$

$O(N)$ (通常比 vector 慢,因为可能涉及跨数据块的移动)

随机访问

$O(1)$ (最快,一次指针偏移)

$O(1)$ (也很快,但比 vector 略慢,涉及两次指针操作)

内存重新分配

当容量不足时,重新分配一块更大的内存,并移动所有元素。

在两端添加时,只需分配新的数据块,无需移动已有元素。仅当中控器满时才需重新分配中控器。

迭代器

连续内存,是普通的指针。

非普通指针,是一个特殊的类,内部维护指向中控器、数据块和当前元素的指针。

总结:

  • 如果你需要频繁在前端插入/删除,请使用 deque

  • 如果你只需要在后端操作,并且需要最快的随机访问和绝对连续的内存(例如与 C API 交互),请使用 vector

  • 如果你在乎内存占用的连续性,vector 更好;deque 会产生内存碎片(多个小块)。

Q5: dequelist 有什么主要区别?

A5:

特性

list (双向链表)

deque (双端队列)

内存布局

非连续内存 (每个节点单独分配)

分块的连续内存

随机访问

$O(N)$ (不支持 [],只能遍历)

$O(1)$ (支持 [],非常高效)

前端插入/删除

$O(1)$ (常数时间)

$O(1)$ (均摊常数时间)

后端插入/删除

$O(1)$ (常数时间)

$O(1)$ (均摊常数时间)

中间插入/删除

$O(1)$ (如果已有迭代器指向该位置)

$O(N)$ (效率很低)

迭代器失效

非常稳定。插入操作不会使迭代器失效;删除操作仅使指向被删除元素的迭代器失效。

不稳定。见 Q6。

内存开销

。每个元素都有额外的指针开销 (前驱和后继)。

中等。有中控器和数据块管理的开销,但分摊到每个元素上通常比 list 少。

总结:

  • 如果你需要高效的随机访问,请在 dequevector 中选择。

  • 如果你需要频繁在中间插入/删除元素,并且希望操作后迭代器保持有效,请使用 list

  • 如果你的需求集中在两端操作,并且也需要随机访问,deque 是完美的选择。

Q6: deque 的迭代器失效规则是怎样的?

A6: deque 的迭代器失效规则比较复杂,介于 vectorlist 之间:

  1. 在两端插入 (push_front, push_back):

    • 迭代器所有已存在的迭代器都失效。(因为中控器(map)可能会被重新分配和拷贝,导致迭代器内部指向中控器的指针失效)。

    • 引用和指针不会失效。(因为数据块本身没有被移动)。

  2. 在两端删除 (pop_front, pop_back):

    • 迭代器:仅指向被删除元素的迭代器失效。

    • 引用和指针:仅指向被删除元素的引用和指针失效。

  3. 在中间插入:

    • 所有迭代器、引用和指针都失效

  4. 在中间删除:

    • 所有迭代器、引用和指针都失效

注意: deque 在两端插入时迭代器会失效,这是它与 vector(后端插入时,若未扩容则迭代器不失效)的一个重要区别,也是面试中容易出错的地方。

Q7: 什么时候应该使用 deque

A7: 当你的应用场景满足以下一个或多个条件时,应优先考虑 deque

  1. 需要频繁在容器的前端和后端进行插入和删除操作。(例如:实现一个队列或双端队列)。

  2. 需要支持高效的随机访问([] 操作)。 (这是它优于 list 的地方)。

  3. 不希望在容器增长时(尤其是前端增长时)移动所有元素。(这是它优于 vector 的地方)。

  4. 可以接受非连续的内存布局。

经典用例:

  • 实现一个队列(Queue)std::queue 默认就是使用 deque 作为其底层容器的。

  • 实现一个滑动窗口(Sliding Window)算法:例如“求窗口中的最大值”,需要在窗口滑动时(一端出、一端进)高效操作,同时可能需要访问窗口内的元素。

  • 任务调度队列。

http://www.dtcms.com/a/515166.html

相关文章:

  • 墨刀可以做网站原型图吗做游戏推广一个月能拿多少钱
  • 《微信小程序》第三章:Request封装
  • 破空驭风,智领未来 --5KG物流配送无人机展示飞行!
  • 全面掌握 PostgreSQL 关系型数据库,PostgreSQL 和 MySQL 的区别,笔记03
  • 做RAG的开发者如何选择合适的开源项目
  • Spring Boot整合JWT实现跨站点统一登录
  • Spring Boot Docker镜像分层优化指南
  • Linux中页面写回初始化page_writeback_init函数实现
  • 神经网络中的随机高斯初始化技术
  • 怎样做网站分流赚钱东莞网站制作哪家公司好
  • HOOPS 3D可视化引擎:覆盖实时渲染与仿真分析的高性能解决方案!
  • 云原生架构下微服务接入 SkyWalking 最佳实践
  • 单片机中的机器周期、指令周期、总线周期的联系和区别
  • spring微服务宏观概念
  • 在阿里云通过docker部署srs流媒体服务器(支持webrtc、http-flv)
  • 【WAF】 Nginx如何集成安全检测服务
  • nginx安装和使用
  • 茂名市建设银行网站今天哈尔滨最新通告
  • 快飞建站月夜直播免费版
  • Windows 11 25H2 更新补丁导致鼠标键盘失灵,紧急更新补丁已推出
  • 移动端 (RN) - 键盘弹出, 不遮挡输入框 (和 底部按钮)的处理方案
  • 【C++闯关笔记】深究继承
  • Python爬虫抓取豆瓣TOP250数据
  • AWS Elemental MediaConvert:视频转码不再难
  • 华为OD最新机试真题-乘坐保密电梯-OD统一考试(C卷)
  • SpringBoot 如何实现零拷贝:深度解析零拷贝技术
  • 问卷调查网站怎么做做百度推广
  • Jenkins 持续集成与部署指南
  • 新书速览|DeepSeek高效数据分析:从数据清洗到行业案例
  • 搜索百科(5):Easysearch — 自主可控的国产分布式搜索引擎