C++学习篇(9)-详解deque、stack、queue的实现原理

       本篇内容主要介绍STL六大组件之一的序列式容器中的deque、stack、queue,如果对文章内容感兴趣,欢迎大家多多关注微信公众号" 爱折腾的码农 ",二维码见下图。另外本人将自己在秋招过程中遇到的一些算法题和总结的典型代码题汇总成word文档和pdf文档。里面内容包括但不限于数据结构中的冒泡、堆排、归并、快排等排序方法,二叉树遍历、前缀树、哈希表实现、LRU、股票买卖、C++读取输入方法的实现方法等内容,如果感兴趣的话可以微信公众号后台回复“ 算法题”,欢迎大家关注。原文链接:https://mp.weixin.qq.com/s/fhA3X_TDcWVkN9Ql5IR5FQ
在这里插入图片描述

deque

1、概述

      vector是单向开口的连续线性空间,但deque一种双向开口的连续线性空间。双向开口的意思是可以在头尾两端分别做元素的插入和删除操作。vector虽然也可以在头尾两端进行插入和删除,但是头部操作的效率奇差,需要之后的元素都向前移动。

图片

dequevector的区别?

    1、deque能够在常数时间在头端插入和删除元素;
    2、deque没有容量的观念,因为它是动态地以分段连续空间组合而成,随时可以增加一段新的空间并链接起来。

图片

deque和vector的使用场合区分

图片


2、deque中控器 实现方法

图片

        注意:其实map就是一个T**的指针,里面每个节点指向一个缓冲区的首地址。

图片

deque为什么需要中控器

图片

3、deque迭代器

deque迭代器需要具备的功能


    1、必须能够指出分段连续空间(就是缓冲区)在哪里;
    2、能够判断自己是否已经处于当前所在的缓冲区边缘,如果是的话,当前进或者后端时就必须跳跃到下一个或者上一个缓冲区,因此deque必须随时掌握中控器map。

    在这里我就不贴上迭代器具体的实现代码了,如果感兴趣可以看《STL源码剖析》第146页,下面我将展示迭代器、缓冲区、中控器三者的关系,如下图所示。

具体分配方式

图片

图片

4、deque数据结构

图片

5、deque分配过程(假设声明好一个deque,其缓冲区大小为32byte,并令其保存20个元素空间,每个元素处置设为9)

    1、给20个元素重新设值,从0~19,另外插入三个新元素,如下图所示;以为之前可能最后还有4个备用元素空间,因此不会引起缓冲区在配置,现在的状态如下图所示。

图片

    2、在deque尾端添加一个新元素;由于尾端只剩一个元素的备用空间,于是调用push_back_aux(),先配置一整块新的缓冲区,再设置新元素内容,最后更改迭代器finish状态;

    3、在deque头部插入元素,由于头部所在的缓冲区没有备用空间,因此需要调用push_front_aux来判断是否需要map扩容,如果不需要扩容map的话,则直接配置一块新的缓冲区并将节点安置在map上,实现过程和第2步一样。

图片

    注意:map中控器扩容步骤类似于vector扩容方式,(1)另觅更大空间;(2)将原数据复制过去;(3)释放原空间;

stack

1、概述

    stack是一种先进后出的数据结构,其只有一个出口,就是说仅允许在一端插入和删除元素,不允许遍历行为。其实在很多地方都可以用到,比如说浏览器中的后退、文件夹后退等功能。

图片

2、STL中stack的实现方法

    1、deque

图片

    

    2、list

    注意:由于stack只允许一端插入和删除元素,不允许遍历,因此其没有迭代器

queue

1、概述

    queue是一种先进先出的数据结构,有两个出口,仅允许一端插入另一端删除。可以类比于我们去银行排队办业务,按序处理,所以queue也不循序有遍历行为。

图片

2、STL中queue的实现方法

    1、deque

图片

        2、list

图片

    注意:queue也不允许遍历,因此也是没有迭代器

       

    本部分之所以介绍stack和queue底层实现,其实是因为我在秋招面试过程中遇到过面试官让写简单的stack或queue,本人建议用deque作为底层容器,写起来比较简单。

猜你喜欢

转载自blog.csdn.net/weixin_43305362/article/details/112909703
今日推荐