deque

deque和vector一眼个都是一种连续的存储在线性空间之中。但是他和vetor的不同在于,vetor是单向开口的(如果在容器前面插入元素,性能会十分低下);而deque是双向开口的一种存储单元,可以保证从头从尾插入的时间复杂度都保证在常数级别。此外,在deque中不存在容量的概念,因为它维护的是一段动态的存储空间,不会出现当存储不够时,配置一更更大的内存空间,将原来的空间拷贝到新的内存空间中,在析构原本的内存空间。

下面介绍一下deque的内存维护:

deque 采用一块连续的空间存放指针,每个指针都指向一个连续的存储空间,成为缓冲区,这些缓冲区才是元素真正存储的空间。每个缓冲区的大小是相同的,所以当计算deque的size时,不需要一个一个遍历元素,是需要计算指针数组中一共使用了多少个指针,和最后一个指针指向缓冲区使用的个数,就可以计算出来。deque中的元素就存在于这一段一段的缓冲区中。如果当存放指针的连续空间不足时,就需要像操作vector空间不足一样,开辟一段更大的内存空间,将原来的指针数组拷贝到新的空间中去。如图:


下面说一下deque的迭代器

deque的实际存储器是一段一段连续的空间,所以要保证迭代的++和--操作,必须由迭代器来保证。

先看下迭代的结构:


其中中控器是指针所存在的连续线性空间,缓冲区buffer是存储deque中真正元素的地方。迭代器中存在四个元素,cur指针指向当前元素,first指针指向当前元素所在连续存储的左边缘,last指向当前元素所在连续存储的右边缘,node指向指针数组中指向自身元素所在连续存储的指针地址。

有了这样的迭代器结构,就可以轻易的保证迭代器的++和--操作,只要迭代器的cur指针指向了缓冲区的边缘,执行++或者--操作时,就到中控器中找到前一个或者后一个缓冲区,调整迭代相应字段的值就可以了。那么如何确保迭代器不会越界呢。在deque中保存了start,和finish两个内部的迭代器,这两个迭代器保存了该deque的头和尾,所以我们操作迭代器是不会越界的。


deque的存储结构和迭代器结构就是如上,下面是deque的几个常用操作。

在初始化时,让start迭代器和finish迭代器保持在中央,这样就可以让头尾扩充的能力一样大

push_back 和push_front两个操作就是在容器的前或者后增加数据,但是这两种操作,在何时开辟新的缓冲区有些不同。

1.start迭代器指向的是容器中第一个可以使用的元素,所以当容器的头部充满缓冲区时,不需要新开辟内存空间,如果当容器的头部已经在一个缓冲区的边缘,还要push_front时,才需要新开辟空间

2.但是finish迭代器指向容器尾部最后一个可使用的元素的下一个空间,所以当容器的最后一个元素占满了缓冲区的最后一个单元时,这时就需要开辟新的空间,将finish指针指向下一个缓冲区的第一个单元了。


find操作是从头遍历整个deque,返回第一个符合要求的元素的迭代器

insert操作和erase操作相似,首先检查插入或者删除的位置,如果前面的元素较少,那么向前方扩张(收缩);如果后面元素较少,反之。假设想前方扩张(收缩),将之前的元素一一移动,如果是插入,将插入的元素赋值给腾出的空间,若是删除,则pop_front第一个元素即可。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值