在STL中,队列和栈的实现都是基于其他的容器所实现的,因为其本身的数据结构需求并不复杂,而且能复用的话为什么不呢?而且实现一个栈或者是队列可以用数组也可以使用链表,那么牵扯到C++,为了实现这种既可以使用数组也可以使用链表的数据结构,产生了容器适配器。
以vector为底层容器实现的结构栈
template<class T, class container = vector<T>>
class mystack
{
public:
//先进后出
mystack()
{}
T& operator[](const size_t pos)
{
return _stack[pos];
}
void push(const T& val)
{
_stack.push_back(val);
}
void pop()
{
_stack.pop_back();
}
T& top() const
{
return _stack.top();
}
size_t size()
{
return _stack.size();
}
private:
container _stack;
};
当然其底层的存放过程依旧是顺序存储的,不过结构栈的顺序需求也只是先进先出,不影响。
结构栈也可以由链表实现,链表的头插头删效率都很高,那么更换底层数据结构的过程就非常简单,我们直接更改container的缺省值就可以,而且它本身就是缺省值我们传递模板参数的时候传递一个list也是可以的。
int main()
{
mystack<int,list<int>> st1;
st1.push(1);
st1.push(1);
st1.push(1);
st1.push(1);
}
在官方的文档库中,结构栈的默认容器则是一个deque,一个双端队列。
双端队列出现的契机则是为了应对list以及vector的短板,vector随机访问效率高但是头插头删效率低下,list随机访问效率低但是头插头删效率高,它们各有优缺,此时为了应对普遍情况,一个中庸却实用的数据结构deque出现了,它虽然没有两者的缺点,但是也没有两者的优点,在作为stack以及队列的基础容器的情况下变得非常适用。但是它本身的结构非常的复杂,这里就不记述了。
总而言之,适配器的设计其实就是将某一个容器进行封装来满足当前某些情况的需要的结构,并且可以转换不同的实现底层。