21 容器deque&queue&stack深度探索(学自Boolean)

来源:互联网 发布:网络客服招聘条件 编辑:程序博客网 时间:2024/06/08 18:09

1、概述

本篇主要介绍STL容器deque的数据结构,deque是属于序列化结构(sequence),可以向容器两端增加或删除数据。deque容器可以当做线性结构使用,而实际上deque的设计是分段连续的,并不是像array或vector一样是连续的,详细介绍如下。而queue堆和stack栈的设计,是复合了容器deque,然后关闭deque的部分功能来实现。

2、G2.9中容器deque结构图分析

解析:

a、deque是通过分段连续实现的,在内存中有一个控制中心,用于存放分段数据即图中buffer的的地址(这些地址是连续存储的),但指向的buffer之间是不连续的;

b、控制中心有一个map:指向控制中心的地址。map size:代表控制中心的大小;

c、deque中的迭代器中有4个元素:cur、first、last、node。其中node代表指向控制中心的位置,cur是代表指向当前buffer的数据,first代表指向当前buffer的首部,last

指向当前buffer的尾部.

d、deque中迭代器有start和finish两个,分别指向node分别指向控制中心的首元素和尾元素。

3、G2.9中容器deque的代码实现

1)容器deque

解析:

a、如deque结构图所示,G2.9容器deque中设计了4个元素start、finish、map和map_size;

b、模板类deque中有三个参数,第一个指存放数据类型,第二个为默认分配器,第三个是Buffer的大小(此时默认是0,用户可以调节);

c、deque使用的迭代器是_deque_iterator,具体结构如下。

d、通过设计函数如begin(),返回start迭代器来取出首元素等等。

2)_deque_iterator迭代器的设计


解析:

a、迭代器设计和list容器迭代器一样,满足5种遵循的原则;

b、如deque迭代器的结构图所示,迭代器中的有4个数据cur、first、last、node。

3、deque如何模拟连续空间

我们在使用deque时,都是当做连续空间内容实现的,而实际如上所以deque是分段连续的,所以在代码中要实现模拟连续空间的操作,是在deque的迭代器中实现的。

1)实现front()\back()\size()等

解析:

a、通过front()和back()可以返回首迭代器和尾迭代器,

b、通过size(),采用首迭代器 - 尾迭代器方法,计算发小(当然减号是要被重载的,因为实际大小还有通过buffer计算);

c、判断deque是否为空,可以通过判断首尾迭代器是否相等得到。

2)实现用*取得当前元素


说明:操作符重载*(),来返回*cur,就能取出当前元素。

3)实现操作符++跳到下一个节点

说明:操作符++有前置++和后置++,只要实现一个即可。如++()通过判断++cur是否跳出当前buffer,通过set_node()函数实现节点的跳转。

4)实现操作符+=连续调动节点

说明:实现+=的过程,就是首先要判断增加的n,是否会跳出buffer区,如果不会跳出直接增加,如果会跳出,则要根据buffer的大小来实现跳转。

4、queue和stack

我们知道堆queue和栈stack分别是能实现先进先出和先进后出的操作。而deque是双向进出的容器,所以可以通过复合deque来实现queue和stack容器,更确切的说

这两个是适配器更为合适。

1)queue

注意点:

a、queue中的数据是底层容器Sequence c,而Sequence正是该类模板中的第二个参数,即deque容器;

b、queue实现的功能如empty(),size()等都是通过deque来实现的。queue先进先出功能是用push_back()和pop_front()实现。

c、deque只开放了部分功能来满足queue。

2)stack

注意点:

a、stack中的数据也是底层容器Sequence c,而Sequence正是该类模板中的第二个参数,即deque容器;

b、stack实现的功能如empty(),size()等都也是通过deque来实现的。stack先进先出功能是用push_back()和pop_back()实现;

c、deque只开放了部分功能来满足stack。

3)使用queue和stack的注意点

  • stack和queue可以选择list或deque为底层容器,标准库默认是deque,因为deque的速度较快;
  • 为了保持stack和queue的功能,这两个容器都没有迭代器,即不能遍历;
  • stack可以选择vector作为底层容器;
  • queue不能选择vector作为底层容器;
  • stack和queue都不能选择set或map为底层容器。

原创粉丝点击