STL之deque

现在学习下deque的正确使用 ,与vector不同的是deque可以在头部,进行添加和删除操作,并且是常数时间的复杂度

#include<string>
#include<deque>
#include<iostream>
using namespace std;
int main()
{
   deque<string>d;
   cout<<"the deque max_size is:"<<d.max_size()<<endl;
 
   d.push_back("1:");
   d.push_back("2");
   d.push_back("3");
   d.push_back("4");
   for(int i=0;i<d.size();i++)
      cout<<d[i]<<endl;
   d.pop_back();
   d.pop_front();
   deque<string>::iterator itr;
   for(itr=d.begin();itr!=d.end();itr++)
     cout<<*itr<<endl;
   d.push_back("first");

   for(itr=d.begin();itr!=d.end();itr++)
      cout<<*itr<<endl;
   d.clear();
  }

deque的元素采用线性结构进行存储,每一个存储块称之为deque块,每一个块的大小一般是512字节,元素类型所占的大小决定了每一个deque块可容纳元素个数的多少,所

有deque块由map块进行管理,每个map块记录各个deque块的首地址,也就是说map块先于deque块的创建,每创建一个deque块,就将其加入到map块中去,deque的迭代

器共有4个变量,一个是m_first  m_last  m_cur   m_node,m_first和m_last指定了第一个deque块第一个元素地址和最后一个deque块最后一个元素地址,而m_cur指定了当前访问的deque双对列的元素的地址 m_node存放当前deque块的map数据项的地址。m_start和m_finish都可以按照“++”和“--” 进行跨块操作,如果--超出了m_start则开辟新的块,将m_start指向新的deque的首地址,同样的,如果“++”超过了m_last,则开辟新的块,进行将m_last移动到新的deque的最后一个元素的地址

这样的话,因为deque元素可动态增长,也就不存在capacity容量操作,这样的话可以认为是容量组的链表

每次当内存不够用时,自动开辟一个deque块,并将该deque块放在map块当中,也就是说理论上不存在不够用的情况。每次添加或者删除一个元素,都会检查该deque块是否已经失效,或者需要新建新的deque块,这样一来,deque的内存管理还是很高效的。,新建一个deque的时候,我们会根据传递的参数(元素个数)和元素类型,决定需要的deque的个数

这里面需要注意的是deque元素的插入没有任何限制,就和vector是一样的,也就是说没有比较函数一说,无论重复与否,都可以放在里面,我们可以认为是内存模型不一致的数组即可

1、我们首先看看插入操作,因为我们在指定的位置上进行插入操作,然而我们需要进行辨别,该位置的特殊性,如果该位置靠近前面的位置上,进行的是一种操作,另一种则是靠近末尾的位置的上,

                          start              pos

                X          A         B       C        D        E          F     

第一步,进行push_front(begin()),变成了

              start                         pos

               A          A         B       C         D        E         F

第二步,进行整个内存的复制

              start                         pos

               A         B        C        C          D        E         F

第三部就是在pos位置上进行赋值了

              start                         pos

               A         B        C        M          D        E         F

而如果pos靠近末尾位置呢,则是

                                     pos                          end

                A         B       C        D        E          F     

第一步,进行push_back(back()),变成了

                                     pos                                       end

               A         B       C         D        E         F          F

第二步,进行整个内存的复制

                                     pos                                     end

               A         B        C        C         D        E         F

第三部就是在pos位置上进行赋值了

                                     pos                                      end

               A         B        M        C          D        E         F

接下来要说的就是删除操作了,同样的需要判断pos位置所在是靠近deque的起始位置还是结束位置

1、如果是起始位置的话,原始图谱是这样的

              start                         pos

               A          B       C         D        E         F

2.进行内存的复制

              start                         pos

               A          A       B         C        E         F

3.去掉第一个pop(front())

              start                         pos

                 A       B         C        E        F

而如果是靠近末尾的元素呢,起始图谱:

1、

                                     pos                          end

                A         B       C        D        E          F     
2\就是,向前复制,调用copy_forward

                                     pos                          end

                A         B       D        E        F          F     

3、最后进行pop(back())操作,去掉最后一个元素

                                     pos           end

                A         B       D        E        F
这样我们就完成了deque的操作,



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

世纪殇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值