1. deque容器 简介

(1)功能:双端数组,可以对头端进行插入删除操作,也可以对尾端进行插入和删除操作。
(2) deque与vector区别:

  1. vector对于头部的插入效率低,数据量越大,效率越低,例如头部后有十万个数据,则往头部插入一个数据时,十万个数据都需要往后挪一挪才能在头部插入数据。deque相对而言,对头部的插入删除速度会比vector快。
  2. vector访问元素时的速度会比deque快,这和两者内部实现有关。
    (3)deque内部工作原理:
    和 vector 容器采用连续的线性空间不同,deque 容器存储数据的空间是由一段一段等长的连续空间构成,各段空间之间并不一定是连续的,可以位于在内存的不同区域。
    为了管理这些连续空间,deque 容器用数组存储着各个连续空间的首地址。也就是说,数组中存储的都是指针,指向那些真正用来存储数据的各个连续空间。
    在这里插入图片描述

通过建立数组,deque 容器申请的这些分段的连续空间就能实现“整体连续”的效果。换句话说,当 deque 容器需要在头部或尾部增加存储空间时,它会申请一段新的连续空间,同时在数组的开头或结尾添加指向该空间的指针,由此该空间就串接到了 deque 容器的头部或尾部。
deque 容器的分段存储结构,提高了在序列两端添加或删除元素的效率,但也使该容器迭代器的底层实现变得更复杂。
(4)deque容器迭代器的底层实现
由于 deque 容器底层将序列中的元素分别存储到了不同段的连续空间中,因此要想实现迭代器的功能,必须先解决如下 2 个问题:
①迭代器在遍历 deque 容器时,必须能够确认各个连续空间在数组中的位置;
②迭代器在遍历某个具体的连续空间时,必须能够判断自己是否已经处于空间的边缘位置。如果是,则一旦前进或者后退,就需要跳跃到上一个或者下一个连续空间中。
实现:迭代器内部包含 4 个指针,它们各自的作用为:
cur:指向当前正在遍历的元素;
first:指向当前连续空间的首地址;
last:指向当前连续空间的末尾地址;
node:它是一个二级指针,用于指向数组中存储的指向当前连续空间的指针。

2. deque常用的操作函数

1. deque<T> deq; //默认构造形式
2. deque<T> d2(d1.begin(),d1.end()); //将d1中[begin,end)区间中的元素拷贝给本身。
3. deque(n,elem);  //构造函数将n个elem拷贝给本身
4. deque(const deque &deq);  //拷贝构造函数
5. deque& operator=(const deque &deq);  //重载等号操作符
6. assign(beg, end);  //将[beg,end)区间中的数据拷贝赋值给本身。
7. assign(n,elem); //将n个elem拷贝赋值给本身。
8. empty(); //判断容器是否为空
9. size(); //返回容器中的元素的个数
10. resize(num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。
                      //如果容器变短,则末尾超出容器长度的元素被删除。
11. resize(num,elem); //重新指定容器的长度为num,若容器变成,则以elem值填充新位置。
                           //如果容器变短,则末尾超出容器长度的元素被删除。
12. push_back(elem);  //在容器尾部添加一个数据
13. push_front(elem);  //在容器头部插入一个数据
14. pop_back();  //删除容器最后一个数据
15. pop_front();  //删除容器第一个数据
16. insert(pos,elem);  //在pos位置插入一个elem元素的拷贝,返回新数据的位置。
17. insert(pos,n,elem); //在pos位置插入n个elem数据,无返回值
18. insert(pos,beg,end);  //在pos位置插入[beg,end)区间的数据,无返回值
19. clear();  //清空容器的所有数据
20. erase(beg,end);  //删除[beg,end)区间的数据,返回下一个数据的位置。
21. erase(pos); //删除pos位置的数据,返回下一个数据的位置。
22. at(int idx); //返回索引idx所指的数据
23. operator[]; //返回索引idx所指的数据
24. front(); //返回容器中第一个数据元素
25. back(); //返回容器中最后一个数据元素

3. 构造函数

(1)功能描述:deque容器构造。
(2)函数原型:

1. deque<T> deq; //默认构造形式
2.  deque<T> d2(d1.begin(),d1.end()); //将d1中[begin,end)区间中的元素拷贝给本身。
3. deque(n,elem);  //构造函数将n个elem拷贝给本身
4. deque(const deque &deq);  //拷贝构造函数

(3)deque容器和vector容器的构造方式几乎一致,灵活使用即可。

#include <iostream>
#include <deque> 

using namespace std;

//deque容器 构造函数

void printDeuque(const deque<int>& d) //const 防止进行写操作,只能进行读
{
    for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)  //表示只读迭代器
    {
        //*it = 100;   const使得当进行写操作时,会报错,会提示,避免了进行修改操作
        cout << *it << " ";
    }
    cout << endl;
}

void test01()
{
    deque<int> d1; //无参构造函数

    for (int i = 0; i < 10; i++)
    {
        d1.push_back(i);
    }
    printDeuque(d1);

    //区间的方式构造
    deque<int> d2(d1.begin(),d1.end());
    printDeuque(d2);

    //n个值的方式构造
    deque<int> d3(10,100);
    printDeuque(d3);
    
    //拷贝构造
    deque<int> d4(d3);
    printDeuque(d4);
}

int main()
{
    test01();

    return 0;
}

运行结果:
在这里插入图片描述

4. 赋值操作

(1)功能描述:给deque容器进行赋值。
(2) 函数原型:

1. deque& operator=(const deque &deq);  //重载等号操作符
2. assign(beg, end);  //将[beg,end)区间中的数据拷贝赋值给本身。
3. assign(n,elem); //将n个elem拷贝赋值给本身。

(3)deque赋值操作与vector相同。

#include <iostream>
#include <deque> 

using namespace std;

//deque容器 赋值操作

void printDeuque(const deque<int>& d) 
{
    for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)  //表示只读迭代器
    {
        cout << *it << " ";
    }
    cout << endl;
}

void test02()
{
    deque<int> d1; 

    for (int i = 0; i < 10; i++)
    {
        d1.push_back(i);
    }
    printDeuque(d1);

    //operator= 赋值
    deque<int> d2;
    d2 = d1;
    printDeuque(d2);

    //assign 赋值
    deque<int> d3;
    d3.assign(d1.begin(), d1.end());
    printDeuque(d3);
    
    deque<int> d4(10,100);
    printDeuque(d4);
}

int main()
{
    test02();
    
    return 0;
}

运行结果:
在这里插入图片描述

5. 大小操作

(1)功能描述:对deque容器的大小进行操作。
(2)函数原型:

1. deque.empty(); //判断容器是否为空
2. deque.size(); //返回容器中的元素的个数
3. deque.resize(num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。
                      //如果容器变短,则末尾超出容器长度的元素被删除。
4. deque.resize(num,elem); //重新指定容器的长度为num,若容器变成,则以elem值填充新位置。
                           //如果容器变短,则末尾超出容器长度的元素被删除。
#include <iostream>
#include <deque> 

using namespace std;

//deque容器 大小操作

void printDeuque(const deque<int>& d) 
{
    for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)  //表示只读迭代器
    {
        cout << *it << " ";
    }
    cout << endl;
}

void test03()
{
    deque<int> d1; 

    for (int i = 0; i < 10; i++)
    {
        d1.push_back(i);
    }
    printDeuque(d1); 

    if (d1.empty())
    {
        cout << "d1为空" << endl;
    }
    else
    {
        cout << "d1不为空" << endl;
        cout << "d1的大小为:" << d1.size() << endl;
        //deque容器没有容量概念
    }
    //重新指定大小
    d1.resize(15, 1); //这里指定填充值为1,如果没有第二个参数,默认的填充值为0
    printDeuque(d1);

    d1.resize(5);
    printDeuque(d1);
}

int main()
{
    test03();

    return 0;
}

运行结果为:
在这里插入图片描述

6. 插入和删除

(1)功能描述:向deque容器中插入和删除数据。
(2)函数原型:

1. push_back(elem);  //在容器尾部添加一个数据
2. push_front(elem);  //在容器头部插入一个数据
3. pop_back();  //删除容器最后一个数据
4. pop_front();  //删除容器第一个数据
5. insert(pos,elem);  //在pos位置插入一个elem元素的拷贝,返回新数据的位置。
6. insert(pos,n,elem); //在pos位置插入n个elem数据,无返回值
7. insert(pos,beg,end);  //在pos位置插入[beg,end)区间的数据,无返回值
8. clear();  //清空容器的所有数据
9. erase(beg,end);  //删除[beg,end)区间的数据,返回下一个数据的位置。
10. erase(pos); //删除pos位置的数据,返回下一个数据的位置。
#include <iostream>
#include <deque> 

using namespace std;

//deque容器 插入和删除

void printDeuque(const deque<int>& d) 
{
    for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)  //表示只读迭代器
    {
        cout << *it << " ";
    }
    cout << endl;
}

void test04()
{
    deque<int> d1; 
    
    //尾插
    d1.push_back(10);
    d1.push_back(20);

    //头插
    d1.push_front(100);
    d1.push_front(200);
    
    printDeuque(d1);

    //尾删
    d1.pop_back();
    printDeuque(d1);

    //头删
    d1.pop_front();
    printDeuque(d1);
}

void test05()
{
    deque<int> d2;
    d2.push_back(10);
    d2.push_back(20);
    d2.push_front(100);
    d2.push_front(200);

    printDeuque(d2);

    d2.insert(d2.begin(), 1000);
    printDeuque(d2);

    d2.insert(d2.begin(), 2, 9999);
    printDeuque(d2);

    deque<int> d3;
    d3.push_back(1);
    d3.push_back(2);
    d3.push_front(3);

    d3.insert(d3.begin(), d2.begin(), d2.end()); //在d3.begin()的位置,插入区间d2.begin()-d2.end()之间的数
    printDeuque(d3);

}

void test06()
{
    deque<int> d1;
    d1.push_back(10);
    d1.push_back(20);
    d1.push_front(100);
    d1.push_front(200);

    //删除
    deque<int>::iterator it = d1.begin();
    it++;
    d1.erase(it); //d1.erase()为删除所有;d1.clear()也为清空容器所有数据
    printDeuque(d1);

    //按区间方式删除
    d1.erase(d1.begin(), d1.end());
    printDeuque(d1);

}

int main()
{
    test04();
    test05();
    test06();

    return 0;
}

运行结果为:
在这里插入图片描述

7. 数据存取

(1)功能描述:对deque中的数据的存取操作。
(2)函数原型:

1. at(int idx); //返回索引idx所指的数据
2. operator[]; //返回索引idx所指的数据
3. front(); //返回容器中第一个数据元素
4. back(); //返回容器中最后一个数据元素

(3)除了用迭代器获取deque容器中元素,[]和at也可以。

#include <iostream>
#include <deque> 

using namespace std;

//deque容器 数据存取

void printDeuque(const deque<int>&d) 
{
    for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)  //表示只读迭代器
    {
        cout << *it << " ";
    }
    cout << endl;
}

void test07()
{
    deque<int> d1; 
    
    //尾插
    d1.push_back(10);
    d1.push_back(20);
    d1.push_back(30);

    //头插
    d1.push_front(100);
    d1.push_front(200);
    d1.push_front(300);

    //通过[]方式访问元素
    //
    for (int i = 0; i < d1.size(); i++)
    {
        cout << d1[i] << " ";
    }
    cout << endl;
    
    //通过at方式访问元素
    for (int i = 0; i < d1.size(); i++)
    {
        cout << d1.at(i) << " ";
    }
    cout << endl;
    
    cout << "第一个元素为:" << d1.front() << endl;
    cout << "最后一个元素为:" << d1.back() << endl;
}

int main()
{
    test07();

    return 0;
}

运行结果为:
在这里插入图片描述

8. 排序

(1)利用算法实现对deque容器进行排序。
(2) 算法:

1. sort(iterator beg, iterator end)  //对beg和end区间内元素进行排序

(3)sort算法非常实用,使用时包含头文件algorithm即可。

#include <iostream>
#include <deque> 
#include <algorithm>  //标准算法头文件

using namespace std;

//deque容器 排序操作

void printDeuque(const deque<int>&d) 
{
    for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)  //表示只读迭代器
    {
        cout << *it << " ";
    }
    cout << endl;
}

void test08()
{
    deque<int>d1; 
    
    //尾插
    d1.push_back(10);
    d1.push_back(20);
    d1.push_back(30);

    //头插
    d1.push_front(100);
    d1.push_front(200);
    d1.push_front(300);

    printDeuque(d1);

    //排序  默认排序规则  从小到大 升序
    //对于支持随机访问的迭代器的容器,都可以利用sort算法直接对其进行排序
    //vector容器也可以利用sort进行排序
    sort(d1.begin(), d1.end());
    cout << "排序后:" << endl;
    printDeuque(d1);
}


int main()
{
    test08();

    return 0;
}

运行结果为:
在这里插入图片描述

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐