deque、queue和stack深度探索(下)

deque如何模拟连续空间?通过源码可以看到这个模型就是通过迭代器来完成。

 迭代器通过重载操作符+,-,++,--,*和->来实现deque连续的假象,如上图中的 finish-start ,它通过下图中重载-号来实现迭代器的相减,返回deque的大小。

用finish迭代器上的node相减(node为控制中心的下标序号)再减1,求得两个首尾两端之间完整buff个数,乘以buff大小,在加上两端非完整buff中元素个数就得到了deque的大小。

再例如对迭代器取*,通过重载函数可以看到它返回了指向buff元素的指针的取*,即返回了元素。

再看看++和--的重载

扫描二维码关注公众号,回复: 8198117 查看本文章

 当前++时,如果cur自增后如果等于last(last指向每个buff最后一个元素的后边),就往后调整node,就是调整迭代器cur指向后一个buff的first,前--的实现也很类似。

deque的迭代器同样提供+=和-=的重载,使使用者觉得其更像一块连续空间

 

在对+=的实现上,它会首先判断要跨越的大小是否在当前buff,如果在,仅移动cur即可,如果不在则移动node跳到相应buff,再让cur指向正确位置。在这里其实已经为-=预留了操作,即代码中的问号表达式,-=也的确是通过调用+=来自我实现的,其实现如下

 这里还对 [] 进行了重载,重载效果即就像数组取值一样。

当map空间不足进行扩充时,已经知道map是由vector实现的,在map拷贝进入新的空间时,它会智能的将map拷贝到新空间的中部,以给左右留有余量以便扩充。

 queue是双端队列,由于之前已经实现了deque,所以在queue的实现上直接使用deque的方法

 所有的方法的实现都是用Sequence的对象来实现。

 

 正是因为其没有独立的实现,所以它也被称为容器适配器。queue和stack也可以通过list来实现

 stack和queue不允许使用set、map来实现其底层,因为这两个的迭代器没有实现它们的功能,所以如果调用就会出错。(虽然可以 这么定义一个queue queue<string, set<string>>;编译器也可以通过)

stack可以用vector来实现底层,但queue不能用vector,究其原因还是由于迭代器的原因。

 

猜你喜欢

转载自www.cnblogs.com/area-h-p/p/12045084.html