1. deque的认识
- deque(双端队列):是双开口的“连续”空间的数据结构,两端都可以进行插入和删除操作,时间复杂度为O(1);
- deque并不是真正的连续空间,而是由一段段连续的小空间拼接而成,分段连续,类似于一个动态的二维数组;
- 与vector相比:头插和删除时,不需要搬移元素,效率特别高,扩容时也不需要搬移大量元素;
- 与list相比:空间利用率比较高,不需要存储额外字段;
- 缺陷:不适合遍历。
deque | vector | list | |
---|---|---|---|
优点 | 支持随机访问(性能略低于vector),头部尾部操作性能高:O(1),增容代价小 | 随机访问,尾部操作,空间利用率高,不容易造成内存碎片 | 任意位置操作性能高:O(1) |
缺点 | 中间位置操作性能比较低:O(n) | 中间头部操作:O(n),增容代价比较大 | 不支持随机访问,空间利用率较低,容易造成内存碎片 |
迭代器失效问题
- vector:底层为连续空间,删除数据,迭代器不失效
- list:底层为不连续空间,删除数据,指向节点的迭代器会失效
- deque:底层为假性连续空间,删除数据,可能会导致迭代器会失效,取决于删除数据的位置
2. stack的实现(deque)
- 栈的构造尾插、尾删、取栈顶元素、返回元素个数、判空操作
template<class T, class Con = deque<T>>
class Stack
{
public:
Stack() {}
void push(const T& x)
{
_c.push_back(x);
}
void pop()
{
_c.pop_back();
}
T& top()
{
return _c.back();
}
const T& top()const
{
return _c.back();
}
size_t size()const
{
return _c.size();
}
bool empty()const
{
return _c.empty();
}
private:
Con _c;
};
3. queue的实现(deque)
- 队列的构造、尾插、头删、取队头队尾元素、返回元素个数、判空操作
template<class T, class Con = deque<T>>
class Queue
{
public:
Queue() {}
void push(const T& x)
{
_c.push_back(x);
}
void pop()
{
_c.pop_front();
}
T& back()
{
return _c.back();
}
const T& back()const
{
return _c.back();
}
T& front()
{
return _c.front();
}
const T& front()const
{
return _c.front();
}
size_t size()const
{
return _c.size();
}
bool empty()const
{
return _c.empty();
}
private:
Con _c;
};