【c++容器】deque双端队列

目录

deque 的特点

双端操作

动态大小

随机访问

内存分配

deque 的常用操作

1. 初始化

2. 元素访问

3. 插入和删除操作

4. 大小管理

5. 迭代器

deque 与 vector 的比较

6.成员函数总结

7.deque成员函数使用实例


如需咨询请添加个人微信:a15135158368

欢迎叨扰,多多交流


deque(双端队列,Double-Ended Queue)是 C++ 标准模板库(STL)中的一种顺序容器,它允许在序列的两端(头部和尾部)快速插入和删除元素。

vector 类似,deque 也是一个动态数组,但它的内存分配和管理方式使得它在两端操作上更加高效。

deque 的特点

  1. 双端操作

    deque 支持在容器的头部和尾部进行快速的插入和删除操作

    复杂度为 O(1)

  2. 动态大小

    deque 会根据需要自动调整其大小,动态分配和释放内存。

  3. 随机访问

    deque 支持随机访问,类似于 vector,可以通过下标操作符 [] 或者 at() 方法访问元素。

  4. 内存分配

    vector 不同,deque 通常会在不同的内存块中存储元素,因此不会像 vector 那样需要一次性分配一大片连续的内存。

deque 的常用操作

1. 初始化

#include <iostream>
#include <deque>
​
int main() 
{
    std::deque<int> d1;                    // 默认构造函数
    std::deque<int> d2(5, 10);             // 构造一个包含 5 个值为 10 的元素的 deque
    std::deque<int> d3 = {1, 2, 3, 4, 5};  // 列表初始化
}

2. 元素访问

#include <iostream>
#include <deque>
​
int main() {
    std::deque<int> d = {1, 2, 3, 4, 5};
​
    // 随机访问
    std::cout << "索引2中的元素 : " << d[2] << std::endl;   // 使用下标操作符
    std::cout << "索引3处的元素 : " << d.at(3) << std::endl; // 使用 at() 方法
​
    // 访问首尾元素
    std::cout << "前部元件 : " << d.front() << std::endl;   // 访问第一个元素
    std::cout << "尾部元素 : " << d.back() << std::endl;     // 访问最后一个元素
}

3. 插入和删除操作

#include <iostream>
#include <deque>
​
int main() 
{
    std::deque<int> d;
​
    // 在头部和尾部插入元素
    d.push_back(1);      // 在尾部插入元素 1
    d.push_front(2);     // 在头部插入元素 2
​
    // 输出 deque 的内容
    std::cout << "Deque : ";
    for (const auto& elem : d) 
    {
        std::cout << elem << " ";
    }
    std::cout << std::endl;
​
    // 在头部和尾部删除元素
    d.pop_back();        // 删除尾部元素
    d.pop_front();       // 删除头部元素
​
    std::cout << "删除后的双端队列 : ";
    for (const auto& elem : d) 
    {
        std::cout << elem << " ";
    }
    std::cout << std::endl;
}

4. 大小管理

#include <iostream>
#include <deque>
​
int main() 
{
    std::deque<int> d = {1, 2, 3, 4, 5};
​
    std::cout << "双端队列的大小 : " << d.size() << std::endl;     // 获取元素个数
​
    d.resize(3);  // 调整大小为 3,超出的元素将被删除
    std::cout << "调整大小后的Deque : ";
    for (const auto& elem : d) 
    {
        std::cout << elem << " ";
    }
    std::cout << std::endl;
}

5. 迭代器

#include <iostream>
#include <deque>
​
int main() {
    std::deque<int> d = {1, 2, 3, 4, 5};
​
    // 使用迭代器遍历 deque
    std::cout << "双端队列中的元素为 : ";
    for (auto it = d.begin(); it != d.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;
​
    // 逆向遍历
    std::cout << "双端队列中的元素(反向) : ";
    for (auto it = d.rbegin(); it != d.rend(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;
}

dequevector 的比较

  • 插入和删除

    • deque 在两端插入和删除元素的操作比 vector 更加高效,因为 vector 只擅长在尾部进行插入和删除操作。

  • 内存分配

    • deque 的内存分配策略使得它在头部和尾部的插入删除操作非常高效,但它的内存布局较 vector 复杂,可能在某些场景下导致缓存性能不如 vector

  • 访问速度

    • vector 在连续内存块中存储数据,通常在遍历和访问元素时性能更好,因为它利用了 CPU 缓存的局部性。

      deque 由于分块存储,可能在访问时稍慢。

6.成员函数总结

代码含义
q.front()返回队首元素
q.back()返回队尾元素
q.push_back()在尾部插入元素
q.push_front()在头部插入元素
q.pop_back()删除尾部元素
q.pop_front删除头部元素
q.size()获取元素的个数
q.resize()调整队列元素个数,超出的元素将删除
q.empty()判断队列是否为空
q.erase()删除双端队列中的某一个元素
q.clear()清空队列

总结改编自作者: 行码棋

链接: C++ STL总结 | 行码棋

7.deque成员函数使用实例

使用以上成员函数编写的一个deque的简单实例:

#include <iostream>
#include <deque>
​
int main() {
    // 创建一个空的双端队列
    std::deque<int> q;
​
    // 使用 push_back() 在队列的末尾添加元素
    q.push_back(10);
    q.push_back(20);
    q.push_back(30);
​
    // 使用 push_front() 在队列的前面添加元素
    q.push_front(5);
    q.push_front(1);
​
    // 显示队列的内容
    std::cout << "队列内容: ";
    for(int n : q) {
        std::cout << n << " ";
    }
    std::cout << std::endl;
​
    // 使用 front() 和 back() 访问队列的第一个和最后一个元素
    std::cout << "队列前面的元素 : " << q.front() << std::endl;
    std::cout << "队列后面的元素 : " << q.back() << std::endl;
​
    // 使用 pop_front() 移除队列前面的元素
    q.pop_front();
    std::cout << "移除前面元素后的队列内容 : ";
    for(int n : q) {
        std::cout << n << " ";
    }
    std::cout << std::endl;
​
    // 使用 pop_back() 移除队列后面的元素
    q.pop_back();
    std::cout << "移除后面元素后的队列内容 : ";
    for(int n : q) {
        std::cout << n << " ";
    }
    std::cout << std::endl;
​
    // 查看队列的大小
    std::cout << "队列大小 : " << q.size() << std::endl;
​
    // 使用 resize() 调整队列的大小
    q.resize(3);  // 将队列大小调整为3,如果原大小大于3,则多余的元素被删除
    std::cout << "调整大小后的队列内容: ";
    for(int n : q) {
        std::cout << n << " ";
    }
    std::cout << std::endl;
​
    // 检查队列是否为空
    if(q.empty()) {
        std::cout << "队列为空" << std::endl;
    } else {
        std::cout << "队列不为空" << std::endl;
    }
​
    return 0;
}

运行结果:

队列内容: 1 5 10 20 30 
队列前面的元素: 1
队列后面的元素: 30
移除前面元素后的队列内容: 5 10 20 30 
移除后面元素后的队列内容: 5 10 20 
队列大小: 3
调整大小后的队列内容: 5 10 20 
队列不为空
  • 18
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值