C++ STL deque容器 基本概念 构造函数 赋值操作 容器大小操作
创始人
2024-06-03 16:22:46
0

deque容器

文章目录

  • deque容器
    • 1 deque容器基本概念
    • 2 deque构造函数
    • 3 deque赋值操作
    • 4 deque大小操作

1 deque容器基本概念

功能: 双端数组,可以对头端进行插入删除操作。

deque与vector区别:

  • vector(单端数组,左闭右开),对于头部的插入删除效率低,数据量越大,效率越低。比如头部插入新数据,需要从头部开始往后移动,预留内存空间再插入新数据
  • deque相对而言,对头部的插入删除速度回比vector
  • vector访问元素时的速度会比deque快,这和两者内部实现有关

deque容器
在这里插入图片描述
front():第一个元素,back():最后一个元素;
begin():起始迭代器,end():结束迭代器;
push_front():头部插入数据,pop_front():头部删除数据;
push_back():尾部插入数据,pop_back():尾部删除数据;
insert():插入数据,对外接口。

deque内部工作原理:

deque内部有个中控器维护每段缓冲区中的节点(内容),缓冲区中存放真实数据

中控器维护的是每个缓冲区的地址,使得使用deque时像一片连续的内存空间

deque容器的迭代器也是支持随机访问的。

在这里插入图片描述

说明:
中控器中维护缓冲区的地址,缓冲区存放有效的数据。
在头部插入时,首地址是0x01,那么新数据首先在这个地址指向的缓冲区插入,当内存不够时,会再找新的缓冲区继续在头部插入数据,新缓冲的地址0x00也会在中控器中存入并维护;
同样地,在尾部插入时,首地址是0x03,新数据在这个地址指向的缓冲区插入,当内存不够时,会再找新的缓冲区继续在尾部插入数据,新缓冲的地址0x04也会在中控器中存入并维护。因此,deque可以实现快速的头部、尾部插入数据。

和vector数组相比,deque访问元素时没有vector快。比如访问第一个元素ele1,中继器要通过这个元素缓冲区的地址0x00访问,访问下一个元素时,要再通过地址0x01才能访问。也就是说,访问元素时,需要通过元素所在的缓冲区来访问。因此,deque头尾插入数据速度快,但是访问数据效率低,但也可以跳跃访问。

2 deque构造函数

功能描述: deque容器构造

函数原型:

  • deque deqT;——————默认构造形式
  • deque(beg, end);——————构造函数将[beg, end)区间中的元素拷贝给本身。
  • deque(n, elem);——————-构造函数将n个elem拷贝给本身。
  • deque(const deque &deq);——-拷贝构造函数

代码示例:

void test1()
{int len = 50;//1、默认构造形式deque d1;for (int i = 1; i < 16; ++i){d1.push_back(i);//尾插}cout << "默认构造\td1:" << endl;printDeque(d1); cout << string(len, '-') << endl;//for (int i = 11; i < 16; ++i)//{//	d1.push_front(i);//头插//}//cout << "头插 d1:" << endl;//printDeque(d1); cout << string(len, '-') << endl;//2、[beg, end)区间构造 左闭右开deque d2(d1.begin(), d1.end());cout << "区间构造\td2:" << endl;printDeque(d2); cout << string(len, '-') << endl;//3、n个elem拷贝构造deque d3(13, 15);cout << "n个elem拷贝构造\td3:" << endl;printDeque(d3); cout << string(len, '-') << endl;//4\拷贝构造deque d4(d3);cout << "拷贝构造\td4:" << endl;printDeque(d4); cout << string(len, '-') << endl;
}

在这里插入图片描述
说明:
以上的构造方法和vector中的一样,不赘述。要注意的是,如果想要容器是一个只读状态,容器可以加入const修饰,相应地,迭代器也要换成有const修饰的迭代器,如下所示。

//打印输出 加入const修饰迭代器 只读不写
void printDeque(const deque& d)
{for (deque::const_iterator it = d.begin(); it != d.end(); it++){//*it = 100;//const_iterator 容器数据不可以被修改cout << *it << "  ";}cout << endl;
}

在这里插入图片描述

解释:
在打印函数中,有可能会对迭代器进行一个写操作,修改其中数据。如果想要这个打印函数只读不写,那么可以加入const修饰deque容器,即const deque& d。如果迭代器还是原来deque::iterator的定义方式,会提示“无法从const iterator…到iterator转换…”。因此,需要把起始迭代器也做修改,换成deque::const_iterator,此时起始迭代器就不能被修改了,变成只读不写的状态。

总结: deque容器和vector容器的构造方式几乎一致,灵活使用即可

3 deque赋值操作

功能描述: 给deque容器进行赋值

函数原型:

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

代码示例:

void printDeque(const deque& d)
{for (deque::const_iterator it = d.begin(); it != d.end(); it++){cout << *it << "  ";}cout << endl;
}void test1()
{int len = 50;deque d1;for (int i = 1; i < 16; ++i){d1.push_back(i);//尾插}cout << "d1:" << endl;printDeque(d1); cout << string(len, '-') << endl;//1、operator=赋值deque d2;d2 = d1;cout << "operator=赋值\td2:" << endl;printDeque(d2); cout << string(len, '-') << endl;//2、assign区间赋值 [beg, end)deque d3;d3.assign(d2.begin(), d2.end());cout << "assign区间赋值\td3:" << endl;printDeque(d3); cout << string(len, '-') << endl;//3、assign n个elem拷贝赋值deque d4;d4.assign(13, 15);cout << "assign n个elem拷贝赋值\td4:" << endl;printDeque(d4); cout << string(len, '-') << endl;
}

在这里插入图片描述
总结: deque赋值操作也与vector相同,需熟练掌握

4 deque大小操作

功能描述: 对deque容器的大小进行操作

函数原型:

  • deque.empty();———————–判断容器是否为空

  • deque.size();————————-返回容器中元素的个数

  • deque.resize(num);——————重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。

  • deque.resize(num, elem);————重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。

注意:

vector容器中是有容量这个概念的,因为这是一个单端数组,左闭右开的范围,容量有限,并且vector有对外的接口capacity()。

但在deque容器中,是没有容量这个概念的,因为这是一个双端数组,可以无限动态扩展 deque容器,左开右开的范围,容量无限 ,所以没有capacity()这个对外接口,只有 大小 这个概念和接口 size()和resize()

代码示例:

void printDeque(const deque& d)
{for (deque::const_iterator it = d.begin(); it != d.end(); it++){//*it = 100;//const_iterator 容器数据不可以被修改cout << *it << "  ";}cout << endl;
}void test1()
{int len = 60;deque d1(13, 15);cout << "d1容器resize前\t" << endl << "d1:  "; printDeque(d1);if (d1.empty()){cout << "容器为空!" << endl;}else{cout << "容器的大小:" << d1.size() << endl;}cout << string(len, '-') << endl;//重新指定大小  比原来小d1.resize(7);//删除超出新大小的数据cout << "d1容器resize后\t" << endl << "d1:  ";printDeque(d1);if (d1.empty()){cout << "容器为空!" << endl;}else{cout << "容器的大小:" << d1.size() << endl;}cout << string(len, '-') << endl;//重新指定大小  比原来大d1.resize(13);//默认值0填充cout << "d1容器resize后\t" << endl << "d1:  ";printDeque(d1);if (d1.empty()){cout << "容器为空!" << endl;}else{cout << "容器的大小:" << d1.size() << endl;}cout << string(len, '-') << endl;//重新指定大小  比原来大d1.resize(16, 15);//指定值填充cout << "d1容器resize后\t" << endl << "d1:  ";printDeque(d1);if (d1.empty()){cout << "容器为空!" << endl;}else{cout << "容器的大小:" << d1.size() << endl;}cout << endl;
}

在这里插入图片描述
注意: resize时,比原来小,删除超出部分;比原来大,可以指定值填充,否则默认值0填充。

总结:

  • deque没有容量的概念
  • 判断是否为空 — empty
  • 返回元素个数 — size
  • 重新指定个数 — resize

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...