deque(c++)学习记录

deque学习记录


首先介绍下deque,deque是一个双向的队列,也就是既可以从队列的前面入队,也可以从队列的后面入队,同样可以从队列的前面出队,也可以从队列的后面出队。用图表示就是
在这里插入图片描述
但是的deque的中数据的存储方式却不是顺序存储或者双向链表一样的离散存储而是下面的结构:
在这里插入图片描述
先别急,首先最中间的map和mapsize,图片上的是map并不是指这个结构是键值对的map,而是一种映射关系,因为里面都是指针,指出去了,指向了在堆上的buffer,二buffer里面才是真正元素存放的地方,这个map里面的指针实际上是存放在一个vector(顺序表)里面,当所有buffer里面都装满了再要装元素的时候就会来扩充这个vector,扩充到原来的两倍,然后将以前vector里面的内容拷贝到新的vector里面,但是并不是拷贝到新的vector的起始位置,比如以前的vector的size是8,现在扩容到16,就会从新的vector的第四个位置开始拷贝,因为这个一个双端队列所以前面和后面都要留位置,再看start和finish这两个(iterator)迭代器,和其他容器一样,容器都会维护start和finish两个迭代器,迭代器的数据结构是四个指针,start迭代器中的cur指针指向的是deque这个双端队列的第一个元素,start里面的first指向的是第一个元素所在的buffer的首地址,start里面的last指向的是第一个元素所在的buffer的尾地址,start里面的node则是指向vector里面的第一个元素的地址,毫无疑问node是一个二级指针,同理finish里面的cur指向的是最后一个buffer中最后一个元素的下一个元素的首地址,first则是最后一个buffer的首地址,finish是最后一个buffer的尾地址。这个整个deque的结构就清楚了,下面是具体的源代码。
在这里插入图片描述
在这里插入图片描述

然后介绍一下deque的一个函数
在这里插入图片描述
函数要传入一个iterator和一个value,首先判断如果这个传进来的迭代器的cur是否和start,finish的cur指向相同的位置,如果是则执行对应的代码如上,因为是双端队列,在首和尾上插入就很简单,但是如果在队伍中间插入呢?就会执行insert_aux函数如下,首先会判断这个插入的位置离队伍首端更近还是离队伍的尾端更近,如果离首端更近就将插入点的元素往前面移然后查到空位上,反之则插到尾端。
在这里插入图片描述

接下来是的确模拟连续空间,连续空间的模拟当然少不了迭代器和操作符重载:
在这里插入图片描述
首先就是类似于数组一样的[]的中括号访问的形式,但是里面是并没有访问到真确的元素的,里面应该是又跳到了迭代器的[]操作符重载函数里面,应该是还会判断是否越界,在哪个缓冲区里面,然后back,size,empty函数里面的被蓝色标记出来的操作符很显然被重载了的,因为在这里很显然会有一些想法,看下面:
在这里插入图片描述
*号操作符里面去返回cur,也就是当前迭代器cur所指向的元素,而->又去调用星号操作符,返回了cur的地址,这是个很好的写法,得记下,就是-操作符重载了,上一张图片上-号操作符是为了计算deque中的元素个数,所以分为三部分,分别是start和finish中完整buffer的数量,然后就是第一个buffer和最后一个buffer中元素的个数,因为第一个和最后一个buffer中可能未填满。

在这里插入图片描述
然后后面的就是++操作符了,如果是vector里面就很简单了,因为是线性的,看第一个++操作符重载,也就是前加加操作符重载了,需要判断是否到了buffer的边界,这里注意一个细节,先让cur执行++操作,假设cur指向buffer的最后一个元素++就会超过buffer所以last应该是指向buffer的尾端,当然如果cur指向buffer的最后一个元素的话,再执行++操作就要移到下一个缓冲区了。而在后加加里面又去调用的前加加,好写法。

在这里插入图片描述
在这里插入图片描述
后面还有几个操作符重载有兴趣的可以自己看看。

这篇文章是学习了侯捷老师的deque分析所写,有错误希望指正

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值