C++进阶 -- std::deque‌ 和 ‌std::list

std::deque ‌ 和 ‌**std::list** ‌ 都是 C++ 标准模板库(STL)中的‌序列容器‌(Sequence Containers)。

它们都属于 <container> 库的一部分,用于存储和管理元素序列,但它们的底层实现、性能特点和适用场景有所不同。

1. std::deque (双端队列)

std::deque 是平衡了随机访问效率和两端操作效率的最佳选择。

类型‌:序列容器(Sequence Container)

  • ‌操作效率 ‌:
    • ‌尾部插入 ‌ (push_back):‌**O(1)**‌
    • ‌头部取值 ‌ (front):‌**O(1)**‌
    • ‌头部删除 ‌ (pop_front):‌O(1) ‌ (这是它优于 std::vector 的关键)
  • ‌额外优势 ‌:
    • 支持随机访问(如 dq[i]),虽然比 vector 稍慢,但远快于 list。
    • 内存由分段连续块组成,扩容时不需要像 vector 那样整体移动数据。
  • ‌适用场景‌:绝大多数需要"尾进头出"或"两端操作"的场景,如滑动窗口、任务队列。
  • ‌底层结构‌:由多个固定大小的缓冲区组成,通过索引表管理。
  • ‌支持随机访问 :可以通过下标 [] 或 at() 快速访问任意元素
  • 分段连续‌:整体不连续,但局部块内连续。不能保证整个容器内存 contiguous。
  • 迭代器失效‌:仅在首尾插入导致扩容时可能失效;中间插入/删除通常只影响被操作位置的迭代器。
cpp 复制代码
#include <deque>
#include <iostream>

int main() {
    std::deque<int> dq;

    // 1. 尾部插入
    dq.push_back(10);
    dq.push_back(20);
    dq.push_back(30);

    // 2. 头部取元素 (不删除)
    if (!dq.empty()) {
        std::cout << "Front element: " << dq.front() << std::endl; // 输出 10
    }

    // 3. 头部删除 (如果需要取出并移除)
    dq.pop_front(); 
    
    return 0;
}

2. std::list (双向链表)

如果你不需要随机访问(下标访问),且主要在中间位置也有频繁插入/删除需求,std::list 是很好的选择。

  • ‌类型‌:序列容器(Sequence Container)。
  • ‌操作效率 ‌:
    • ‌尾部插入 ‌ (push_back):‌**O(1)**‌
    • ‌头部取值 ‌ (front):‌**O(1)**‌
    • ‌头部删除 ‌ (pop_front):‌**O(1)**‌
  • ‌劣势 ‌:
    • ‌不支持随机访问 ‌:无法使用 [] 或 at(),遍历需 O(N)。
    • ‌内存开销大‌:每个节点需存储前后指针。
    • ‌缓存不友好 ‌:节点分散在堆内存中,遍历速度慢于 deque。
  • ‌底层结构 ‌:‌双向链表‌-节点分散在堆内存中,每个节点包含数据及指向前后节点的指针。
  • ‌支持随机访问 :‌不支持 ‌-访问第 N 个元素需要遍历链表,复杂度为 ‌**O(N)**‌。
  • 连续性‌:节点分散分配,缓存局部性较差。
  • 迭代器失效 ‌:指向其他元素的迭代器在插入/删除操作中‌永远保持有效‌(除了被删除节点的迭代器)。

3. std::queue(队列适配器)

如果你的操作严格遵循 ‌FIFO(先进先出) ‌ 模式,即只允许‌尾部插入 ‌和‌头部取出/删除 ‌,可以使用容器适配器 std::queue。

  • ‌类型 ‌:容器适配器(Container Adapter),‌不是‌独立的容器。
  • 底层结构 ‌:默认基于 std::deque 实现,也可以指定使用 std::list 或 std::vector(需满足特定接口要求)作为底层容器。
  • ‌特点‌:封装了底层容器,仅暴露队列操作接口(FIFO:先进先出),限制了用户的操作权限(如禁止随机访问、禁止头部插入等)。
  • ‌底层默认容器 ‌:std::deque。
  • ‌接口限制 ‌:
    • push():尾部插入。
    • front():获取头部元素引用。
    • pop():删除头部元素(注意:pop 返回 void,需先 front 取值再 pop)。
  • ‌优势‌:语义清晰,防止误用其他不支持的操作(如随机访问或头部插入)。
cpp 复制代码
#include <queue>
#include <iostream>

int main() {
    std::queue<int> q;

    // 尾部插入
    q.push(10);
    q.push(20);

    // 头部取元素
    std::cout << "Front: " << q.front() << std::endl; // 输出 10

    // 头部删除
    q.pop();

    return 0;
}
相关推荐
晗夜未央1 分钟前
任务队列反复失败,先分清重试、阻塞和结果待核对
开发语言·javascript
熊猫钓鱼>_>4 分钟前
四种书签,一条时间线:一个读书 App 的记忆颗粒与它的边界案例【鸿蒙心迹】
开发语言·华为·ai编程·harmonyos·鸿蒙·openharmony·鸿蒙pc
Fuyo_111928 分钟前
C++ AVL树保姆级详解:从平衡因子到四大旋转机制
java·c++·算法
努力努力再努力wz39 分钟前
【Lua 入门系列】Lua 函数深入理解:函数对象、多返回值、可变参数、闭包、递归与尾调用优化
开发语言·lua
飞浪纪元[FWC–FE]1 小时前
从零到一键绿:Qt 5.14.2 + VS2019 开发环境搭建、Kit 套件配置与构建错误修复完全手册
开发语言·qt
Wang's Blog1 小时前
Java 项目实战:交友项目 - 联系人列表
java·开发语言·交友
傲世仙尊2 小时前
继承-类设计层次复用切片转换与菱形继承的死结
c++
我命由我123452 小时前
访客系统形式(有用户概念、无用户概念)
java·开发语言·前端·javascript·python·产品运营·产品经理
架构师伯子明2 小时前
FFmpeg C++学习(一):编译和demo
开发语言·c++·学习
海域云SeaArea_2 小时前
Windows Server 2008 R2 从零安装 IIS7.5(二):php.ini 配置
开发语言·windows·php