C++ STL之deque双端队列

deque与vector非常相似,不仅可在尾部插入和删除,还可在头部插入和删除,但是内部的数据机制和执行性能与vector不同,一般来说,当考虑到容器元素的内存分配策略和操作的性能时,deque比vector有优势。

  1. 技术原理
    deque的元素数据采用分块的线性结构进行存储,如下图所示。deque分成若干线性存储块,称为deque块,所以的deque块使用一个Map块进行管理,每个Map数据项记录各个deque块的首地址。Map是deque的中心部件,将先于deque块,依照deque的个数计算deque的块数,作为Map块的数据项数,创建出Map块。
    在Map块和deque块的结构下,deque使用了两个迭代器M_start和M_finish,对首个deque块和末个deque进行访问。
    deque数据结构
    M_start用于push_front函数,M_finish用于push_back函数,所以能在队首和队尾高效的添加元素。

  2. deque应用基础
    deque对象的创建、初始化赋值、元素的遍历访问、反向遍历与vector相同,只是把vector换成deque,这里就不多加赘述了。
    2.1元素的插入
    由于deque使用了两个迭代器分别指向双端队列的首尾,因此,deque具有高效的头部插入元素的函数push_back()。其他位置的插入,将涉及相关元素的移位拷贝,例如insert函数。直接上简单明了的代码:

#include <QCoreApplication>
#include <iostream>
#include <deque>
using namespace std;
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    deque<int> d;
    d.push_back(6);
    d.push_back(7);
    d.push_front(5);//头部插入5
    for(int i=0;i<d.size();i++)
    {
        cout << d[i] << ' ';
    }
    cout << endl;
    d.insert(d.begin() +1,9);//在第二个元素前插入9
    for(int j=0;j<d.size();j++)
    {
        cout << d[j] << ' ';
    }
    cout << endl;
    return a.exec();
}

运行结果:
插入运行结果
2.2元素的删除
直接上一看就懂的代码

#include <QCoreApplication>
#include <iostream>
#include <deque>
using namespace std;
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    deque<int> d;
    d.push_back(4);
    d.push_back(5);
    d.push_back(3);
    d.push_back(3);
    d.push_back(3);
    d.push_back(6);
    for(int i=0;i<d.size();i++)
    {
        cout << d[i] << ' ';
    }
    cout << endl;
    d.erase(d.begin()+1);     //删除第二个元素d[1]
    d.pop_front();           //删除第一个元素
    d.pop_back();            //删除末尾元素
    for(int j=0;j<d.size();j++)
    {
        cout << d[j] << ' ';
    }
    cout << endl;
    d.clear();
    cout << "执行clear()" << endl << "全部清除deque元素" <<endl;
    return a.exec();
}

运行结果:
删除运行结果
2.3deque的交换
废话不多说,看代码就能懂

#include <QCoreApplication>
#include <iostream>
#include <deque>
using namespace std;
void print(deque<int>& d)       //元素打印
{
    for(int j=0;j<d.size();j++)
    {
        cout << d[j] << ' ';
    }
    cout << endl;
}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    deque<int> d1;
    d1.push_back(3);
    d1.push_back(4);
    d1.push_back(5);
    cout << "d1=";
    print(d1);
    deque<int> d2;
    d2.push_back(7);
    d2.push_back(8);
    d2.push_back(9);
    cout << "d2=";
    print(d2);
    d1.swap(d2);   //d1与d2交换
    cout << "d1与d2交换后" << endl;
    cout << "d1=";
    print(d1);
    cout << "d2=";
    print(d2);
    return a.exec();
}

运行结果:
deque交换结果
2.4deque其他常用函数
简单粗暴的上代码:

#include <QCoreApplication>
#include <iostream>
#include <deque>
#include<string>
using namespace std;
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    deque<string> d1;
    cout << "d1是否为空:" << d1.empty() << endl;        //判断容器是否为空,是返回true,否则false
    d1.push_back("红楼梦");
    d1.push_back("源氏物语");
    d1.push_back("教父");
    d1.push_back("水浒传");
    d1.push_back("24史");
    deque<string>::iterator i,iend;
    iend=d1.end();
    for(i=d1.begin();i!=iend;i++)
    {
        cout << *i << " ";
    }
    cout << endl;
    cout << "deque首元素为:" << d1.front() << endl;
    cout << "deque末元素为:" << d1.back() << endl;
    cout << "deque元素个数为:"<< d1.size() << endl;
    cout << "deque最大元素个数为:"<< d1.max_size() << endl;
    return a.exec();
}

运行结果:
deque常用函数运行结果
3. 小结
deque双端队列容器采用分块的线性结构来存储数据,两个迭代器分别指向容器的首尾元素,具有高效的删除首尾元素的push_front和pop_front函数。由于deque容器是以deque块为单位进行内存分配,并使用了二级的Map进行管理,因此不易于实现类似于vector的capacity和reverse函数,而且deque容器也不需要这样的获取和调整容器大小的函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值