STL的Deque介绍

Deque是双端队列,在画动态图表的时候使用起来比较方便。因为当数据填满图表后,需要从队列的后方插入一个元素,然后再从队列的前方删除一个元素。使用Deque可以很方便的做到。使用push(pop)-back(front)就ok了

下面摘录了一个Deque的使用教程

/*deque: 是一个double-ended queue,
    1)支持随即存取,也就是[]操作符,
    2)支持两端操作,push(pop)-back(front),在两端操作上与list效率差不多

    因此在实际使用时,如何选择这三个容器中哪一个,应根据你的需要而定,一般应遵循下面的原则: 
    1、如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector 
    2、如果你需要大量的插入和删除,而不关心随即存取,则应使用list 
    3、如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque。
*/

#include <iostream>
#include <deque>
using namespace std;

void printDeque(deque<int> d)
{
//使用下标
//for (unsigned int i = 0; i < d.size(); i++)
//{
// cout<<"d["<<i<<"] = "<<d[i]<<", ";
//}

//使用迭代器
//deque<int>::iterator iter = d.begin();
//for (;iter != d.end(); iter ++)
//{
// cout<<"d["<<iter-d.begin()<<"] = "<<(*iter)<<", ";
//}

//使用迭代器指针
deque<int>::iterator *pIter = new deque<int>::iterator;
if ( NULL == pIter )
{
   return ;
}
for (*pIter = d.begin(); *pIter != d.end(); (*pIter)++)
{
   cout<<"d["<<*pIter - d.begin() <<"]="<<**pIter<<", ";
}
if (NULL != pIter)
{
   delete pIter;
   pIter = NULL;
}

cout<<endl;
}

void main()
{
//创建deque
deque<int> d1; //创建一个没有任何元素的deque对象
deque<int> d2(10);//创建一个具有10个元素的deque对象,每个元素值为默认
deque<double> d3(10, 5.5); //伊妹一个具有10个元素的deque对象,每个元素的初始值为5.5
deque<double> d4(d3); //通过拷贝一个deque对象的元素值, 创建一个新的deque对象
int iArray[] = {11, 13, 19, 23, 27};
deque<int> d5(iArray, iArray+5);//将迭代器区间[first, last)所指的元素拷贝到一个新创建的deque对象中

//初始化赋值:同vector一样,使用尾部插入函数push_back()
for (int i = 1; i < 6 ; i++)
   d1.push_back(i*10);
//遍历元素: 1-下标方式 2-迭代器方式 反向遍历(略)
cout<<"printDeque(d1) : "<<endl;
printDeque(d1);

//元素插入:尾部插入用push_back(),头部插入用push_front(),其它位置插入用insert(&pos, elem)
cout<<"d1.push_front(100): "<<endl;
d1.push_front(100);
printDeque(d1);
cout<<"d1.insert(d1.begin()+3, 200): "<<endl; //支持随机存取(即[]操作符),所以begin()可以+3
d1.insert(d1.begin()+2,200);
printDeque(d1);

//元素删除 尾部删除用pop_back();头部删除用pop_front(); 
//任意迭代位置或迭代区间上的元素删除用erase(&pos)/erase(&first, &last);删除所有元素用clear();
cout<<"d1.pop_front(): "<<endl;
d1.pop_front();
printDeque(d1);

cout<<"d1.erase(d1.begin()+1): "<<endl;
d1.erase(d1.begin()+1); //删除第2个元素d1[1]
printDeque(d1);

cout<<"d1.erase(d1.begin(), d1.begin() + 2) = "<<endl;
d1.erase(d1.begin(), d1.begin() + 2);
printDeque(d1);

cout<<"d1.clear() :"<<endl;
d1.clear();
printDeque(d1);


//其它常用
cout<<"其它常用用法: "<<endl;
int flag = 0;
while(flag < 2)
{
   if (0 == flag )
   {
    for (int i = 1; i < 6 ; i++) //恢复
     d1.push_back(i*10);
   }
   else
   {
    d1.clear();
    cout<<"after d1.clear() , d1.front(), d1.back() is abnormal! other info.:"<<endl;
   }
   cout<<"d1.empty() = "<<d1.empty()<<endl;
   cout<<"d1.size() = "<<d1.size()<<endl;
   cout<<"d1.max_size() = "<<hex<<d1.max_size()<<endl;
   if (!d1.empty())
   {
    cout<<"d1.front() = "<<d1.front()<<endl;
    cout<<"d1.back() = "<<d1.back()<<endl;
   }
  
   flag++;
  
}

//交换
cout<<"d1.swap(d5)= "<<endl;
d1.swap(d5);
cout<<"d1 = ";
printDeque(d1);
cout<<"d5 = ";
printDeque(d5);
//printDeque(d)


}

转载于:https://www.cnblogs.com/leixiaohua1020/p/3902171.html

### 关于C++ STL `deque` 的用法与实现 #### 定义与基本特性 `std::deque` 是 C++ 标准模板库(STL)提供的一种双端队列容器。它的名称来源于 **double-ended queue**,表示可以从两端高效地插入和删除元素[^3]。 `deque` 提供了随机访问的能力,类似于数组或向量 (`vector`),但它在头部和尾部的插入/删除操作上更加高效。然而,由于其内部存储结构的原因,在中间位置插入或删除元素可能会比较慢。 --- #### 内部实现机制 `deque` 的典型实现方式是通过一系列固定大小的连续内存块来管理数据。这些内存块通常被称为“缓冲区”,而整个 `deque` 则由一个动态分配的指针数组控制,该数组指向各个缓冲区。这种设计使得: - 头部和尾部可以独立扩展。 - 随机访问的时间复杂度为 O(1),因为可以通过简单的计算定位到目标元素所在的缓冲区及其偏移量。 以下是简化版的伪代码描述 `deque` 的核心逻辑: ```cpp template<typename T> class Deque { private: size_t buffer_size; // 缓冲区大小 T** map; // 动态指针数组,用于记录各缓冲区地址 size_t map_size; // 当前map容量 size_t start_index; // 起始缓冲区索引 size_index end_index; // 结束缓冲区索引 public: void push_back(const T& value); void push_front(const T& value); void pop_back(); void pop_front(); }; ``` 具体来说,当需要增加新的缓冲区时,会重新调整 `map` 数组并分配额外的空间;如果某个缓冲区内存不足,则会在同一缓冲区内移动现有元素以腾出空间[^4]。 --- #### 常见成员函数及用法示例 | 函数名 | 描述 | |----------------|----------------------------------------------------------------------| | `push_back(x)` | 将元素 x 添加至 deque 的末尾 | | `pop_back()` | 删除 deque 的最后一个元素 | | `push_front(x)`| 将元素 x 添加至 deque 的开头 | | `pop_front()` | 删除 deque 的第一个元素 | | `front()` | 返回 deque 的首个元素 | | `back()` | 返回 deque 的最后一位元素 | | `at(n)` | 访问第 n 个元素 | 下面是一个完整的例子展示如何使用 `deque` 进行常见操作: ```cpp #include <iostream> #include <deque> int main() { std::deque<int> d; // 向后添加元素 d.push_back(10); d.push_back(20); // 向前添加元素 d.push_front(5); // 输出所有元素 for(auto it = d.begin(); it != d.end(); ++it){ std::cout << *it << ' '; } // 移除首尾元素 d.pop_front(); d.pop_back(); return 0; } ``` 上述程序将依次打印:`5 10 20` 和最终剩余的 `10`. --- #### 性能特点对比其他容器 相比 `vector` 或者链表(`list`),`deque` 在某些场景下具有独特的优势: - **头尾增删效率高**: 对于频繁执行 head/tail 操作的应用场合非常合适; - **支持随机访问**: 不像单双向链表那样仅限迭代器遍历; - **内存碎片较少**: 使用预定义长度的小块缓存减少了零散分布的可能性[^5]. 不过需要注意的是,尽管提供了高效的两端修改能力,但由于涉及多级间接寻址以及可能引发多次重映射等问题,因此整体性能开销仍高于单纯线性布局的数据结构如 vector[]. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值