一、vector与list的优缺点
- vector的优点:下标的随机访问,尾插,尾删效率高。CPU高速缓存命中率高
- vector的缺点:扩容(效率,空间浪费),不适合头插头删。
连续的物理空间为他带来了优点也带来了缺点,可谓成也萧何败也萧何
- list的优点: 按需申请和释放空间,任意位置O(1)的插入删除
- list的缺点:不支持下标的随机访问
那有没有一种容器既有vector的优点又有list的优点呢,于是deque被大佬们研究出来 。
deque 叫做双端队列,但是它不是队列。它设计的初衷是融合vector和list的优点,组成一个全新的容器,大有替代vector和list的趋势。
二、deque的简单介绍
1.deque的接口
不能看出,从它的接口角度就可以看出它想要替代掉vector和list。但是它失败了,因为它四不像,vector和list在它俩的优点方面做到了极致。deque是啥都会一点,但是不精通。
但是deque 也不是完全没用,栈和队列用它刚刚好。或者有时候你既要头插头删,尾插尾删,又随机访问的时候用它也挺好。
2.deque的原理介绍
deque这一段段连续的空间就叫做buffer,假设一个buffer里放8个数据就满了,满了以后我就扩容,我再去找一个buffer,物理上虽然不是连续的,但逻辑上他俩是连续的。头插的话,我还是再开上一个buffer,这样就解决了vector的头插和尾插,及空间连续的问题。
然后还设计了一个中控指针数组进行管理这些buffer,比如我开第一个buffer的时候,把这个buffer的指针存在中间位置,头插就在前面位置存一个buffer的地址,尾插就在它后面存一个buffer的地址
如何支持随机访问呢?
假设每个buffer里是8个数据,进行deque[i]操作的时候,首先看i是不是小于第一个buffer的值,如果大于就进行/看是在第几个buffer里,然后%8看是在buffer里的第几个值,进行判断越界。所以这个随机也不是很随,因为他要进行很多的运算。所以如果要频繁的调用[]就不太好了,但是比起list有比较好。
而且deque在中间位置进行插入和删除也很麻烦,且栈和队列也不需要在中间位置进行插入与删除
中控的指针数组的迭代器里有四个指针,两个指针指向指针的开始和结束一个指针指向当前访问的位置,迭代器++就是cur++,当cur等于last的时候就结束,解引用迭代器就是取cur这个位置。当cur等于last结束时跳转下一个buffer的时候,就通过这个node指针,node存储的是指针数组的地址,对node++就找到下一个位置了,也就是下一个buffer。
3.deque的缺陷
4. 为什么选择deque作为stack和queue的底层默认容器