愿煦风和日永远卫护着可爱的你。
在stl中,stack(栈)与queue(队列)都是容器适配器。
什么是容器适配器呢?
适配器(adaptor)是标准库中通用的概念,包括容器适配器、迭代器适配器和函数适配器。本质上,适配器是使一事物的行为类似于另一事物的行为的一种机制。容器适配器让一种已存在的容器类型采用另一种不同的抽象类型的工作方式实现。简单来说其实就是利用现有的容器来适配出来的新容器。
stack
在标准库中,stack默认使用的是deque容器来进行适配的。 当然这里也可以适配vector容器和list容器。
namespace ZJ
{
template<class T,class Container= ZJ::deque<T>>
class stack
{
public:
void pop()
{
m_stack.pop_back();
}
void push(const T&val)
{
m_stack.push_back(val);
}
size_t size() const
{
return static_cast<size_t>(m_stack.size());
}
T& top()
{
return m_stack.back();
}
const T& top() const
{
return m_stack.back();
}
bool empty() const
{
return m_stack.empty();
}
private:
Container m_stack;
};
}
queue
与stack一样,在标准库中默认使用的是deque容器来进行适配的。
namespace ZJ
{
template<class T,class Container=ZJ::deque<T>>
class queue
{
public:
void pop()
{
m_queue.pop_front();
}
void push(const T& val)
{
m_queue.push_back(val);
}
size_t size() const
{
return static_cast<size_t>(m_queue.size());
}
T& back()
{
return m_queue.back();
}
const T& back() const
{
return m_queue.back();
}
T& front()
{
return m_queue.front();
}
const T& front() const
{
return m_queue.front();
}
bool empty() const
{
return m_queue.empty();
}
private:
Container m_queue;
};
}
为什么选择deque作为stack和queue的底层默认容器
stack是一种后进先出的特殊线性数据结构,因此只要具有push_back()和pop_back()操作的线性结构,都可以作为stack的底层容器,比如vector和list都可以; queue是先进先出的特殊线性数据结构,只要具有push_back和pop_front操作的线性结构,都可以作为queue的底层容器,比如list。 但是STL中对stack和queue默认选择deque作为其底层容器,主要是因为:
- stack和queue不需要遍历(因此stack和queue没有迭代器),只需要在固定的一端或者两端进行操作。
- 在stack中元素增长时,deque比vector的效率高(扩容时不需要搬移大量数据);queue中的元素增长时,deque不仅效率高,而且内存使用率高。
但是deque有一个致命缺陷:不适合遍历,特别是在遍历或者排序时,deque的迭代器要频繁的去检测其是否移动到某段小空间的边界,导致效率低下。
如果小伙伴还没看懂可以在评论区留言,我会在评论区给你解答! 如有错误之处还请各位指出!!! 那本篇文章就到这里啦,下次再见啦!
|